home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 2012-12-14 | 1.3 MB | 49,646 lines
Text Truncated. Only the first 1MB is shown below. Download the file for the complete contents.
Object.isEmpty = function(obj) { for (var i in obj) return false; return true; } Object.values = function(obj) { var keys = Object.keys(obj); var result = []; for (var i = 0; i < keys.length; ++i) result.push(obj[keys[i]]); return result; } String.prototype.hasSubstring = function(string, caseInsensitive) { if (!caseInsensitive) return this.indexOf(string) !== -1; return this.match(new RegExp(string.escapeForRegExp(), "i")); } String.prototype.findAll = function(string) { var matches = []; var i = this.indexOf(string); while (i !== -1) { matches.push(i); i = this.indexOf(string, i + string.length); } return matches; } String.prototype.lineEndings = function() { if (!this._lineEndings) { this._lineEndings = this.findAll("\n"); this._lineEndings.push(this.length); } return this._lineEndings; } String.prototype.escapeCharacters = function(chars) { var foundChar = false; for (var i = 0; i < chars.length; ++i) { if (this.indexOf(chars.charAt(i)) !== -1) { foundChar = true; break; } } if (!foundChar) return this; var result = ""; for (var i = 0; i < this.length; ++i) { if (chars.indexOf(this.charAt(i)) !== -1) result += "\\"; result += this.charAt(i); } return result; } String.prototype.escapeForRegExp = function() { return this.escapeCharacters("^[]{}()\\.$*+?|"); } String.prototype.escapeHTML = function() { return this.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """); } String.prototype.collapseWhitespace = function() { return this.replace(/[\s\xA0]+/g, " "); } String.prototype.trimMiddle = function(maxLength) { if (this.length <= maxLength) return this; var leftHalf = maxLength >> 1; var rightHalf = maxLength - leftHalf - 1; return this.substr(0, leftHalf) + "\u2026" + this.substr(this.length - rightHalf, rightHalf); } String.prototype.trimEnd = function(maxLength) { if (this.length <= maxLength) return this; return this.substr(0, maxLength - 1) + "\u2026"; } String.prototype.trimURL = function(baseURLDomain) { var result = this.replace(/^(https|http|file):\/\//i, ""); if (baseURLDomain) result = result.replace(new RegExp("^" + baseURLDomain.escapeForRegExp(), "i"), ""); return result; } function sanitizeHref(href) { return href && href.trim().toLowerCase().startsWith("javascript:") ? "" : href; } String.prototype.removeURLFragment = function() { var fragmentIndex = this.indexOf("#"); if (fragmentIndex == -1) fragmentIndex = this.length; return this.substring(0, fragmentIndex); } String.prototype.startsWith = function(substring) { return !this.lastIndexOf(substring, 0); } String.prototype.endsWith = function(substring) { return this.indexOf(substring, this.length - substring.length) !== -1; } Number.constrain = function(num, min, max) { if (num < min) num = min; else if (num > max) num = max; return num; } Date.prototype.toISO8601Compact = function() { function leadZero(x) { return x > 9 ? '' + x : '0' + x } return this.getFullYear() + leadZero(this.getMonth() + 1) + leadZero(this.getDate()) + 'T' + leadZero(this.getHours()) + leadZero(this.getMinutes()) + leadZero(this.getSeconds()); } Object.defineProperty(Array.prototype, "remove", { value: function(value, onlyFirst) { if (onlyFirst) { var index = this.indexOf(value); if (index !== -1) this.splice(index, 1); return; } var length = this.length; for (var i = 0; i < length; ++i) { if (this[i] === value) this.splice(i, 1); } } }); Object.defineProperty(Array.prototype, "keySet", { value: function() { var keys = {}; for (var i = 0; i < this.length; ++i) keys[this[i]] = true; return keys; } }); Object.defineProperty(Array.prototype, "upperBound", { value: function(value) { var first = 0; var count = this.length; while (count > 0) { var step = count >> 1; var middle = first + step; if (value >= this[middle]) { first = middle + 1; count -= step + 1; } else count = step; } return first; } }); Object.defineProperty(Array.prototype, "rotate", { value: function(index) { var result = []; for (var i = index; i < index + this.length; ++i) result.push(this[i % this.length]); return result; } }); Object.defineProperty(Uint32Array.prototype, "sort", { value: Array.prototype.sort }); (function() { var partition = { value: function(comparator, left, right, pivotIndex) { function swap(array, i1, i2) { var temp = array[i1]; array[i1] = array[i2]; array[i2] = temp; } var pivotValue = this[pivotIndex]; swap(this, right, pivotIndex); var storeIndex = left; for (var i = left; i < right; ++i) { if (comparator(this[i], pivotValue) < 0) { swap(this, storeIndex, i); ++storeIndex; } } swap(this, right, storeIndex); return storeIndex; } }; Object.defineProperty(Array.prototype, "partition", partition); Object.defineProperty(Uint32Array.prototype, "partition", partition); var sortRange = { value: function(comparator, leftBound, rightBound, k) { function quickSortFirstK(array, comparator, left, right, k) { if (right <= left) return; var pivotIndex = Math.floor(Math.random() * (right - left)) + left; var pivotNewIndex = array.partition(comparator, left, right, pivotIndex); quickSortFirstK(array, comparator, left, pivotNewIndex - 1, k); if (pivotNewIndex < left + k - 1) quickSortFirstK(array, comparator, pivotNewIndex + 1, right, k); } if (leftBound === 0 && rightBound === (this.length - 1) && k === this.length) this.sort(comparator); else quickSortFirstK(this, comparator, leftBound, rightBound, k); return this; } } Object.defineProperty(Array.prototype, "sortRange", sortRange); Object.defineProperty(Uint32Array.prototype, "sortRange", sortRange); })(); Object.defineProperty(Array.prototype, "qselect", { value: function(k, comparator) { if (k < 0 || k >= this.length) return; if (!comparator) comparator = function(a, b) { return a - b; } var low = 0; var high = this.length - 1; for (;;) { var pivotPosition = this.partition(comparator, low, high, Math.floor((high + low) / 2)); if (pivotPosition === k) return this[k]; else if (pivotPosition > k) high = pivotPosition - 1; else low = pivotPosition + 1; } } }); function binarySearch(object, array, comparator) { var first = 0; var last = array.length - 1; while (first <= last) { var mid = (first + last) >> 1; var c = comparator(object, array[mid]); if (c > 0) first = mid + 1; else if (c < 0) last = mid - 1; else return mid; } return -(first + 1); } Object.defineProperty(Array.prototype, "binaryIndexOf", { value: function(value, comparator) { var result = binarySearch(value, this, comparator); return result >= 0 ? result : -1; } }); Object.defineProperty(Array.prototype, "select", { value: function(field) { var result = new Array(this.length); for (var i = 0; i < this.length; ++i) result[i] = this[i][field]; return result; } }); function insertionIndexForObjectInListSortedByFunction(anObject, aList, aFunction) { var index = binarySearch(anObject, aList, aFunction); if (index < 0) return -index - 1; else { while (index > 0 && aFunction(anObject, aList[index - 1]) === 0) index--; return index; } } Array.convert = function(list) { return Array.prototype.slice.call(list); } String.sprintf = function(format, var_arg) { return String.vsprintf(format, Array.prototype.slice.call(arguments, 1)); } String.tokenizeFormatString = function(format, formatters) { var tokens = []; var substitutionIndex = 0; function addStringToken(str) { tokens.push({ type: "string", value: str }); } function addSpecifierToken(specifier, precision, substitutionIndex) { tokens.push({ type: "specifier", specifier: specifier, precision: precision, substitutionIndex: substitutionIndex }); } function isDigit(c) { return !!/[0-9]/.exec(c); } var index = 0; for (var precentIndex = format.indexOf("%", index); precentIndex !== -1; precentIndex = format.indexOf("%", index)) { addStringToken(format.substring(index, precentIndex)); index = precentIndex + 1; if (isDigit(format[index])) { var number = parseInt(format.substring(index), 10); while (isDigit(format[index])) ++index; if (number > 0 && format[index] === "$") { substitutionIndex = (number - 1); ++index; } } var precision = -1; if (format[index] === ".") { ++index; precision = parseInt(format.substring(index), 10); if (isNaN(precision)) precision = 0; while (isDigit(format[index])) ++index; } if (!(format[index] in formatters)) { addStringToken(format.substring(precentIndex, index + 1)); ++index; continue; } addSpecifierToken(format[index], precision, substitutionIndex); ++substitutionIndex; ++index; } addStringToken(format.substring(index)); return tokens; } String.standardFormatters = { d: function(substitution) { return !isNaN(substitution) ? substitution : 0; }, f: function(substitution, token) { if (substitution && token.precision > -1) substitution = substitution.toFixed(token.precision); return !isNaN(substitution) ? substitution : (token.precision > -1 ? Number(0).toFixed(token.precision) : 0); }, s: function(substitution) { return substitution; } } String.vsprintf = function(format, substitutions) { return String.format(format, substitutions, String.standardFormatters, "", function(a, b) { return a + b; }).formattedResult; } String.format = function(format, substitutions, formatters, initialValue, append) { if (!format || !substitutions || !substitutions.length) return { formattedResult: append(initialValue, format), unusedSubstitutions: substitutions }; function prettyFunctionName() { return "String.format(\"" + format + "\", \"" + substitutions.join("\", \"") + "\")"; } function warn(msg) { console.warn(prettyFunctionName() + ": " + msg); } function error(msg) { console.error(prettyFunctionName() + ": " + msg); } var result = initialValue; var tokens = String.tokenizeFormatString(format, formatters); var usedSubstitutionIndexes = {}; for (var i = 0; i < tokens.length; ++i) { var token = tokens[i]; if (token.type === "string") { result = append(result, token.value); continue; } if (token.type !== "specifier") { error("Unknown token type \"" + token.type + "\" found."); continue; } if (token.substitutionIndex >= substitutions.length) { error("not enough substitution arguments. Had " + substitutions.length + " but needed " + (token.substitutionIndex + 1) + ", so substitution was skipped."); result = append(result, "%" + (token.precision > -1 ? token.precision : "") + token.specifier); continue; } usedSubstitutionIndexes[token.substitutionIndex] = true; if (!(token.specifier in formatters)) { warn("unsupported format character \u201C" + token.specifier + "\u201D. Treating as a string."); result = append(result, substitutions[token.substitutionIndex]); continue; } result = append(result, formatters[token.specifier](substitutions[token.substitutionIndex], token)); } var unusedSubstitutions = []; for (var i = 0; i < substitutions.length; ++i) { if (i in usedSubstitutionIndexes) continue; unusedSubstitutions.push(substitutions[i]); } return { formattedResult: result, unusedSubstitutions: unusedSubstitutions }; } function createSearchRegex(query, caseSensitive, isRegex) { var regexFlags = caseSensitive ? "g" : "gi"; var regexObject; if (isRegex) { try { regexObject = new RegExp(query, regexFlags); } catch (e) { } } if (!regexObject) regexObject = createPlainTextSearchRegex(query, regexFlags); return regexObject; } function createPlainTextSearchRegex(query, flags) { var regexSpecialCharacters = "[](){}+-*.,?\\^$|"; var regex = ""; for (var i = 0; i < query.length; ++i) { var c = query.charAt(i); if (regexSpecialCharacters.indexOf(c) != -1) regex += "\\"; regex += c; } return new RegExp(regex, flags || ""); } function countRegexMatches(regex, content) { var text = content; var result = 0; var match; while (text && (match = regex.exec(text))) { if (match[0].length > 0) ++result; text = text.substring(match.index + 1); } return result; } function numberToStringWithSpacesPadding(value, symbolsCount) { var numberString = value.toString(); var paddingLength = Math.max(0, symbolsCount - numberString.length); var paddingString = Array(paddingLength + 1).join("\u00a0"); return paddingString + numberString; } var Map = function() { this._map = {}; this._size = 0; } Map._lastObjectIdentifier = 0; Map.prototype = { put: function(key, value) { var objectIdentifier = key.__identifier; if (!objectIdentifier) { objectIdentifier = ++Map._lastObjectIdentifier; key.__identifier = objectIdentifier; } if (!this._map[objectIdentifier]) ++this._size; this._map[objectIdentifier] = [key, value]; }, remove: function(key) { var result = this._map[key.__identifier]; delete this._map[key.__identifier]; --this._size; return result ? result[1] : undefined; }, keys: function() { return this._list(0); }, values: function() { return this._list(1); }, _list: function(index) { var result = new Array(this._size); var i = 0; for (var objectIdentifier in this._map) result[i++] = this._map[objectIdentifier][index]; return result; }, get: function(key) { var entry = this._map[key.__identifier]; return entry ? entry[1] : undefined; }, size: function() { return this._size; }, clear: function() { this._map = {}; this._size = 0; } } function loadXHR(url, async, callback) { function onReadyStateChanged() { if (xhr.readyState !== XMLHttpRequest.DONE) return; if (xhr.status === 200) { callback(xhr.responseText); return; } callback(null); } var xhr = new XMLHttpRequest(); xhr.open("GET", url, async); if (async) xhr.onreadystatechange = onReadyStateChanged; xhr.send(null); if (!async) { if (xhr.status === 200 || xhr.status === 0) return xhr.responseText; return null; } return null; } function StringPool() { this.reset(); } StringPool.prototype = { intern: function(string) { if (string === "__proto__") return "__proto__"; var result = this._strings[string]; if (result === undefined) { this._strings[string] = string; result = string; } return result; }, reset: function() { this._strings = Object.create(null); }, internObjectStrings: function(obj, depthLimit) { if (typeof depthLimit !== "number") depthLimit = 100; else if (--depthLimit < 0) throw "recursion depth limit reached in StringPool.deepIntern(), perhaps attempting to traverse cyclical references?"; for (var field in obj) { switch (typeof obj[field]) { case "string": obj[field] = this.intern(obj[field]); break; case "object": this.internObjectStrings(obj[field], depthLimit); break; } } } } var _importedScripts = {}; function importScript(scriptName) { if (_importedScripts[scriptName]) return; _importedScripts[scriptName] = true; var xhr = new XMLHttpRequest(); xhr.open("GET", scriptName, false); xhr.send(null); window.eval(xhr.responseText + "\n//@ sourceURL=" + scriptName); } __whitespace = {" ":true, "\t":true, "\n":true, "\f":true, "\r":true}; difflib = { defaultJunkFunction: function (c) { return __whitespace.hasOwnProperty(c); }, stripLinebreaks: function (str) { return str.replace(/^[\n\r]*|[\n\r]*$/g, ""); }, stringAsLines: function (str) { var lfpos = str.indexOf("\n"); var crpos = str.indexOf("\r"); var linebreak = ((lfpos > -1 && crpos > -1) || crpos < 0) ? "\n" : "\r"; var lines = str.split(linebreak); for (var i = 0; i < lines.length; i++) { lines[i] = difflib.stripLinebreaks(lines[i]); } return lines; }, __reduce: function (func, list, initial) { if (initial != null) { var value = initial; var idx = 0; } else if (list) { var value = list[0]; var idx = 1; } else { return null; } for (; idx < list.length; idx++) { value = func(value, list[idx]); } return value; }, __ntuplecomp: function (a, b) { var mlen = Math.max(a.length, b.length); for (var i = 0; i < mlen; i++) { if (a[i] < b[i]) return -1; if (a[i] > b[i]) return 1; } return a.length == b.length ? 0 : (a.length < b.length ? -1 : 1); }, __calculate_ratio: function (matches, length) { return length ? 2.0 * matches / length : 1.0; }, __isindict: function (dict) { return function (key) { return dict.hasOwnProperty(key); }; }, __dictget: function (dict, key, defaultValue) { return dict.hasOwnProperty(key) ? dict[key] : defaultValue; }, SequenceMatcher: function (a, b, isjunk) { this.set_seqs = function (a, b) { this.set_seq1(a); this.set_seq2(b); } this.set_seq1 = function (a) { if (a == this.a) return; this.a = a; this.matching_blocks = this.opcodes = null; } this.set_seq2 = function (b) { if (b == this.b) return; this.b = b; this.matching_blocks = this.opcodes = this.fullbcount = null; this.__chain_b(); } this.__chain_b = function () { var b = this.b; var n = b.length; var b2j = this.b2j = {}; var populardict = {}; for (var i = 0; i < b.length; i++) { var elt = b[i]; if (b2j.hasOwnProperty(elt)) { var indices = b2j[elt]; if (n >= 200 && indices.length * 100 > n) { populardict[elt] = 1; delete b2j[elt]; } else { indices.push(i); } } else { b2j[elt] = [i]; } } for (var elt in populardict) { if (populardict.hasOwnProperty(elt)) { delete b2j[elt]; } } var isjunk = this.isjunk; var junkdict = {}; if (isjunk) { for (var elt in populardict) { if (populardict.hasOwnProperty(elt) && isjunk(elt)) { junkdict[elt] = 1; delete populardict[elt]; } } for (var elt in b2j) { if (b2j.hasOwnProperty(elt) && isjunk(elt)) { junkdict[elt] = 1; delete b2j[elt]; } } } this.isbjunk = difflib.__isindict(junkdict); this.isbpopular = difflib.__isindict(populardict); } this.find_longest_match = function (alo, ahi, blo, bhi) { var a = this.a; var b = this.b; var b2j = this.b2j; var isbjunk = this.isbjunk; var besti = alo; var bestj = blo; var bestsize = 0; var j = null; var j2len = {}; var nothing = []; for (var i = alo; i < ahi; i++) { var newj2len = {}; var jdict = difflib.__dictget(b2j, a[i], nothing); for (var jkey in jdict) { if (jdict.hasOwnProperty(jkey)) { j = jdict[jkey]; if (j < blo) continue; if (j >= bhi) break; newj2len[j] = k = difflib.__dictget(j2len, j - 1, 0) + 1; if (k > bestsize) { besti = i - k + 1; bestj = j - k + 1; bestsize = k; } } } j2len = newj2len; } while (besti > alo && bestj > blo && !isbjunk(b[bestj - 1]) && a[besti - 1] == b[bestj - 1]) { besti--; bestj--; bestsize++; } while (besti + bestsize < ahi && bestj + bestsize < bhi && !isbjunk(b[bestj + bestsize]) && a[besti + bestsize] == b[bestj + bestsize]) { bestsize++; } while (besti > alo && bestj > blo && isbjunk(b[bestj - 1]) && a[besti - 1] == b[bestj - 1]) { besti--; bestj--; bestsize++; } while (besti + bestsize < ahi && bestj + bestsize < bhi && isbjunk(b[bestj + bestsize]) && a[besti + bestsize] == b[bestj + bestsize]) { bestsize++; } return [besti, bestj, bestsize]; } this.get_matching_blocks = function () { if (this.matching_blocks != null) return this.matching_blocks; var la = this.a.length; var lb = this.b.length; var queue = [[0, la, 0, lb]]; var matching_blocks = []; var alo, ahi, blo, bhi, qi, i, j, k, x; while (queue.length) { qi = queue.pop(); alo = qi[0]; ahi = qi[1]; blo = qi[2]; bhi = qi[3]; x = this.find_longest_match(alo, ahi, blo, bhi); i = x[0]; j = x[1]; k = x[2]; if (k) { matching_blocks.push(x); if (alo < i && blo < j) queue.push([alo, i, blo, j]); if (i+k < ahi && j+k < bhi) queue.push([i + k, ahi, j + k, bhi]); } } matching_blocks.sort(difflib.__ntuplecomp); var i1 = j1 = k1 = block = 0; var non_adjacent = []; for (var idx in matching_blocks) { if (matching_blocks.hasOwnProperty(idx)) { block = matching_blocks[idx]; i2 = block[0]; j2 = block[1]; k2 = block[2]; if (i1 + k1 == i2 && j1 + k1 == j2) { k1 += k2; } else { if (k1) non_adjacent.push([i1, j1, k1]); i1 = i2; j1 = j2; k1 = k2; } } } if (k1) non_adjacent.push([i1, j1, k1]); non_adjacent.push([la, lb, 0]); this.matching_blocks = non_adjacent; return this.matching_blocks; } this.get_opcodes = function () { if (this.opcodes != null) return this.opcodes; var i = 0; var j = 0; var answer = []; this.opcodes = answer; var block, ai, bj, size, tag; var blocks = this.get_matching_blocks(); for (var idx in blocks) { if (blocks.hasOwnProperty(idx)) { block = blocks[idx]; ai = block[0]; bj = block[1]; size = block[2]; tag = ''; if (i < ai && j < bj) { tag = 'replace'; } else if (i < ai) { tag = 'delete'; } else if (j < bj) { tag = 'insert'; } if (tag) answer.push([tag, i, ai, j, bj]); i = ai + size; j = bj + size; if (size) answer.push(['equal', ai, i, bj, j]); } } return answer; } this.get_grouped_opcodes = function (n) { if (!n) n = 3; var codes = this.get_opcodes(); if (!codes) codes = [["equal", 0, 1, 0, 1]]; var code, tag, i1, i2, j1, j2; if (codes[0][0] == 'equal') { code = codes[0]; tag = code[0]; i1 = code[1]; i2 = code[2]; j1 = code[3]; j2 = code[4]; codes[0] = [tag, Math.max(i1, i2 - n), i2, Math.max(j1, j2 - n), j2]; } if (codes[codes.length - 1][0] == 'equal') { code = codes[codes.length - 1]; tag = code[0]; i1 = code[1]; i2 = code[2]; j1 = code[3]; j2 = code[4]; codes[codes.length - 1] = [tag, i1, Math.min(i2, i1 + n), j1, Math.min(j2, j1 + n)]; } var nn = n + n; var groups = []; for (var idx in codes) { if (codes.hasOwnProperty(idx)) { code = codes[idx]; tag = code[0]; i1 = code[1]; i2 = code[2]; j1 = code[3]; j2 = code[4]; if (tag == 'equal' && i2 - i1 > nn) { groups.push([tag, i1, Math.min(i2, i1 + n), j1, Math.min(j2, j1 + n)]); i1 = Math.max(i1, i2-n); j1 = Math.max(j1, j2-n); } groups.push([tag, i1, i2, j1, j2]); } } if (groups && groups[groups.length - 1][0] == 'equal') groups.pop(); return groups; } this.ratio = function () { matches = difflib.__reduce( function (sum, triple) { return sum + triple[triple.length - 1]; }, this.get_matching_blocks(), 0); return difflib.__calculate_ratio(matches, this.a.length + this.b.length); } this.quick_ratio = function () { var fullbcount, elt; if (this.fullbcount == null) { this.fullbcount = fullbcount = {}; for (var i = 0; i < this.b.length; i++) { elt = this.b[i]; fullbcount[elt] = difflib.__dictget(fullbcount, elt, 0) + 1; } } fullbcount = this.fullbcount; var avail = {}; var availhas = difflib.__isindict(avail); var matches = numb = 0; for (var i = 0; i < this.a.length; i++) { elt = this.a[i]; if (availhas(elt)) { numb = avail[elt]; } else { numb = difflib.__dictget(fullbcount, elt, 0); } avail[elt] = numb - 1; if (numb > 0) matches++; } return difflib.__calculate_ratio(matches, this.a.length + this.b.length); } this.real_quick_ratio = function () { var la = this.a.length; var lb = this.b.length; return _calculate_ratio(Math.min(la, lb), la + lb); } this.isjunk = isjunk ? isjunk : difflib.defaultJunkFunction; this.a = this.b = null; this.set_seqs(a, b); } } Node.prototype.rangeOfWord = function(offset, stopCharacters, stayWithinNode, direction) { var startNode; var startOffset = 0; var endNode; var endOffset = 0; if (!stayWithinNode) stayWithinNode = this; if (!direction || direction === "backward" || direction === "both") { var node = this; while (node) { if (node === stayWithinNode) { if (!startNode) startNode = stayWithinNode; break; } if (node.nodeType === Node.TEXT_NODE) { var start = (node === this ? (offset - 1) : (node.nodeValue.length - 1)); for (var i = start; i >= 0; --i) { if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) { startNode = node; startOffset = i + 1; break; } } } if (startNode) break; node = node.traversePreviousNode(stayWithinNode); } if (!startNode) { startNode = stayWithinNode; startOffset = 0; } } else { startNode = this; startOffset = offset; } if (!direction || direction === "forward" || direction === "both") { node = this; while (node) { if (node === stayWithinNode) { if (!endNode) endNode = stayWithinNode; break; } if (node.nodeType === Node.TEXT_NODE) { var start = (node === this ? offset : 0); for (var i = start; i < node.nodeValue.length; ++i) { if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) { endNode = node; endOffset = i; break; } } } if (endNode) break; node = node.traverseNextNode(stayWithinNode); } if (!endNode) { endNode = stayWithinNode; endOffset = stayWithinNode.nodeType === Node.TEXT_NODE ? stayWithinNode.nodeValue.length : stayWithinNode.childNodes.length; } } else { endNode = this; endOffset = offset; } var result = this.ownerDocument.createRange(); result.setStart(startNode, startOffset); result.setEnd(endNode, endOffset); return result; } Node.prototype.traverseNextTextNode = function(stayWithin) { var node = this.traverseNextNode(stayWithin); if (!node) return; while (node && node.nodeType !== Node.TEXT_NODE) node = node.traverseNextNode(stayWithin); return node; } Node.prototype.rangeBoundaryForOffset = function(offset) { var node = this.traverseNextTextNode(this); while (node && offset > node.nodeValue.length) { offset -= node.nodeValue.length; node = node.traverseNextTextNode(this); } if (!node) return { container: this, offset: 0 }; return { container: node, offset: offset }; } Element.prototype.removeStyleClass = function(className) { this.classList.remove(className); } Element.prototype.removeMatchingStyleClasses = function(classNameRegex) { var regex = new RegExp("(^|\\s+)" + classNameRegex + "($|\\s+)"); if (regex.test(this.className)) this.className = this.className.replace(regex, " "); } Element.prototype.addStyleClass = function(className) { this.classList.add(className); } Element.prototype.hasStyleClass = function(className) { return this.classList.contains(className); } Element.prototype.positionAt = function(x, y) { if (typeof x === "number") this.style.setProperty("left", x + "px"); else this.style.removeProperty("left"); if (typeof y === "number") this.style.setProperty("top", y + "px"); else this.style.removeProperty("top"); } Element.prototype.pruneEmptyTextNodes = function() { var sibling = this.firstChild; while (sibling) { var nextSibling = sibling.nextSibling; if (sibling.nodeType === Node.TEXT_NODE && sibling.nodeValue === "") this.removeChild(sibling); sibling = nextSibling; } } Element.prototype.isScrolledToBottom = function() { return this.scrollTop + this.clientHeight === this.scrollHeight; } function Size(width, height) { this.width = width; this.height = height; } Element.prototype.measurePreferredSize = function() { document.body.appendChild(this); this.positionAt(0, 0); var result = new Size(this.offsetWidth, this.offsetHeight); this.positionAt(undefined, undefined); document.body.removeChild(this); return result; } Node.prototype.enclosingNodeOrSelfWithNodeNameInArray = function(nameArray) { for (var node = this; node && node !== this.ownerDocument; node = node.parentNode) for (var i = 0; i < nameArray.length; ++i) if (node.nodeName.toLowerCase() === nameArray[i].toLowerCase()) return node; return null; } Node.prototype.enclosingNodeOrSelfWithNodeName = function(nodeName) { return this.enclosingNodeOrSelfWithNodeNameInArray([nodeName]); } Node.prototype.enclosingNodeOrSelfWithClass = function(className) { for (var node = this; node && node !== this.ownerDocument; node = node.parentNode) if (node.nodeType === Node.ELEMENT_NODE && node.hasStyleClass(className)) return node; return null; } Node.prototype.enclosingNodeWithClass = function(className) { if (!this.parentNode) return null; return this.parentNode.enclosingNodeOrSelfWithClass(className); } Element.prototype.query = function(query) { return this.ownerDocument.evaluate(query, this, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; } Element.prototype.removeChildren = function() { if (this.firstChild) this.textContent = ""; } Element.prototype.isInsertionCaretInside = function() { var selection = window.getSelection(); if (!selection.rangeCount || !selection.isCollapsed) return false; var selectionRange = selection.getRangeAt(0); return selectionRange.startContainer.isSelfOrDescendant(this); } Element.prototype.createChild = function(elementName, className) { var element = this.ownerDocument.createElement(elementName); if (className) element.className = className; this.appendChild(element); return element; } DocumentFragment.prototype.createChild = Element.prototype.createChild; Element.prototype.createTextChild = function(text) { var element = this.ownerDocument.createTextNode(text); this.appendChild(element); return element; } DocumentFragment.prototype.createTextChild = Element.prototype.createTextChild; Element.prototype.totalOffsetLeft = function() { return this.totalOffset().left; } Element.prototype.totalOffsetTop = function() { return this.totalOffset().top; } Element.prototype.totalOffset = function() { var totalLeft = 0; var totalTop = 0; for (var element = this; element; element = element.offsetParent) { totalLeft += element.offsetLeft; totalTop += element.offsetTop; if (this !== element) { totalLeft += element.clientLeft - element.scrollLeft; totalTop += element.clientTop - element.scrollTop; } } return { left: totalLeft, top: totalTop }; } Element.prototype.scrollOffset = function() { var curLeft = 0; var curTop = 0; for (var element = this; element; element = element.scrollParent) { curLeft += element.scrollLeft; curTop += element.scrollTop; } return { left: curLeft, top: curTop }; } function AnchorBox(x, y, width, height) { this.x = x || 0; this.y = y || 0; this.width = width || 0; this.height = height || 0; } Element.prototype.offsetRelativeToWindow = function(targetWindow) { var elementOffset = new AnchorBox(); var curElement = this; var curWindow = this.ownerDocument.defaultView; while (curWindow && curElement) { elementOffset.x += curElement.totalOffsetLeft(); elementOffset.y += curElement.totalOffsetTop(); if (curWindow === targetWindow) break; curElement = curWindow.frameElement; curWindow = curWindow.parent; } return elementOffset; } Element.prototype.boxInWindow = function(targetWindow) { targetWindow = targetWindow || this.ownerDocument.defaultView; var anchorBox = this.offsetRelativeToWindow(window); anchorBox.width = Math.min(this.offsetWidth, window.innerWidth - anchorBox.x); anchorBox.height = Math.min(this.offsetHeight, window.innerHeight - anchorBox.y); return anchorBox; } Element.prototype.setTextAndTitle = function(text) { this.textContent = text; this.title = text; } KeyboardEvent.prototype.__defineGetter__("data", function() { switch (this.type) { case "keypress": if (!this.ctrlKey && !this.metaKey) return String.fromCharCode(this.charCode); else return ""; case "keydown": case "keyup": if (!this.ctrlKey && !this.metaKey && !this.altKey) return String.fromCharCode(this.which); else return ""; } }); Event.prototype.consume = function(preventDefault) { this.stopImmediatePropagation(); if (preventDefault) this.preventDefault(); this.handled = true; } Text.prototype.select = function(start, end) { start = start || 0; end = end || this.textContent.length; if (start < 0) start = end + start; var selection = this.ownerDocument.defaultView.getSelection(); selection.removeAllRanges(); var range = this.ownerDocument.createRange(); range.setStart(this, start); range.setEnd(this, end); selection.addRange(range); return this; } Element.prototype.selectionLeftOffset = function() { var selection = window.getSelection(); if (!selection.containsNode(this, true)) return null; var leftOffset = selection.anchorOffset; var node = selection.anchorNode; while (node !== this) { while (node.previousSibling) { node = node.previousSibling; leftOffset += node.textContent.length; } node = node.parentNode; } return leftOffset; } Node.prototype.isAncestor = function(node) { if (!node) return false; var currentNode = node.parentNode; while (currentNode) { if (this === currentNode) return true; currentNode = currentNode.parentNode; } return false; } Node.prototype.isDescendant = function(descendant) { return !!descendant && descendant.isAncestor(this); } Node.prototype.isSelfOrAncestor = function(node) { return !!node && (node === this || this.isAncestor(node)); } Node.prototype.isSelfOrDescendant = function(node) { return !!node && (node === this || this.isDescendant(node)); } Node.prototype.traverseNextNode = function(stayWithin) { var node = this.firstChild; if (node) return node; if (stayWithin && this === stayWithin) return null; node = this.nextSibling; if (node) return node; node = this; while (node && !node.nextSibling && (!stayWithin || !node.parentNode || node.parentNode !== stayWithin)) node = node.parentNode; if (!node) return null; return node.nextSibling; } Node.prototype.traversePreviousNode = function(stayWithin) { if (stayWithin && this === stayWithin) return null; var node = this.previousSibling; while (node && node.lastChild) node = node.lastChild; if (node) return node; return this.parentNode; } HTMLTextAreaElement.prototype.moveCursorToEnd = function() { var length = this.value.length; this.setSelectionRange(length, length); } function isEnterKey(event) { return event.keyCode !== 229 && event.keyIdentifier === "Enter"; } function consumeEvent(e) { e.consume(); } function TreeOutline(listNode, nonFocusable) { this.children = []; this.selectedTreeElement = null; this._childrenListNode = listNode; this.childrenListElement = this._childrenListNode; this._childrenListNode.removeChildren(); this.expandTreeElementsWhenArrowing = false; this.root = true; this.hasChildren = false; this.expanded = true; this.selected = false; this.treeOutline = this; this.comparator = null; this.searchable = false; this.searchInputElement = null; this.setFocusable(!nonFocusable); this._childrenListNode.addEventListener("keydown", this._treeKeyDown.bind(this), true); this._childrenListNode.addEventListener("keypress", this._treeKeyPress.bind(this), true); this._treeElementsMap = new Map(); this._expandedStateMap = new Map(); } TreeOutline.prototype.setFocusable = function(focusable) { if (focusable) this._childrenListNode.setAttribute("tabIndex", 0); else this._childrenListNode.removeAttribute("tabIndex"); } TreeOutline.prototype.appendChild = function(child) { var insertionIndex; if (this.treeOutline.comparator) insertionIndex = insertionIndexForObjectInListSortedByFunction(child, this.children, this.treeOutline.comparator); else insertionIndex = this.children.length; this.insertChild(child, insertionIndex); } TreeOutline.prototype.insertChild = function(child, index) { if (!child) throw("child can't be undefined or null"); var previousChild = (index > 0 ? this.children[index - 1] : null); if (previousChild) { previousChild.nextSibling = child; child.previousSibling = previousChild; } else { child.previousSibling = null; } var nextChild = this.children[index]; if (nextChild) { nextChild.previousSibling = child; child.nextSibling = nextChild; } else { child.nextSibling = null; } this.children.splice(index, 0, child); this.hasChildren = true; child.parent = this; child.treeOutline = this.treeOutline; child.treeOutline._rememberTreeElement(child); var current = child.children[0]; while (current) { current.treeOutline = this.treeOutline; current.treeOutline._rememberTreeElement(current); current = current.traverseNextTreeElement(false, child, true); } if (child.hasChildren && typeof(child.treeOutline._expandedStateMap.get(child.representedObject)) !== "undefined") child.expanded = child.treeOutline._expandedStateMap.get(child.representedObject); if (!this._childrenListNode) { this._childrenListNode = this.treeOutline._childrenListNode.ownerDocument.createElement("ol"); this._childrenListNode.parentTreeElement = this; this._childrenListNode.classList.add("children"); if (this.hidden) this._childrenListNode.classList.add("hidden"); } child._attach(); } TreeOutline.prototype.removeChildAtIndex = function(childIndex) { if (childIndex < 0 || childIndex >= this.children.length) throw("childIndex out of range"); var child = this.children[childIndex]; this.children.splice(childIndex, 1); var parent = child.parent; if (child.deselect()) { if (child.previousSibling) child.previousSibling.select(); else if (child.nextSibling) child.nextSibling.select(); else parent.select(); } if (child.previousSibling) child.previousSibling.nextSibling = child.nextSibling; if (child.nextSibling) child.nextSibling.previousSibling = child.previousSibling; if (child.treeOutline) { child.treeOutline._forgetTreeElement(child); child.treeOutline._forgetChildrenRecursive(child); } child._detach(); child.treeOutline = null; child.parent = null; child.nextSibling = null; child.previousSibling = null; } TreeOutline.prototype.removeChild = function(child) { if (!child) throw("child can't be undefined or null"); var childIndex = this.children.indexOf(child); if (childIndex === -1) throw("child not found in this node's children"); this.removeChildAtIndex.call(this, childIndex); } TreeOutline.prototype.removeChildren = function() { for (var i = 0; i < this.children.length; ++i) { var child = this.children[i]; child.deselect(); if (child.treeOutline) { child.treeOutline._forgetTreeElement(child); child.treeOutline._forgetChildrenRecursive(child); } child._detach(); child.treeOutline = null; child.parent = null; child.nextSibling = null; child.previousSibling = null; } this.children = []; } TreeOutline.prototype._rememberTreeElement = function(element) { if (!this._treeElementsMap.get(element.representedObject)) this._treeElementsMap.put(element.representedObject, []); var elements = this._treeElementsMap.get(element.representedObject); if (elements.indexOf(element) !== -1) return; elements.push(element); } TreeOutline.prototype._forgetTreeElement = function(element) { if (this._treeElementsMap.get(element.representedObject)) { var elements = this._treeElementsMap.get(element.representedObject); elements.remove(element, true); if (!elements.length) this._treeElementsMap.remove(element.representedObject); } } TreeOutline.prototype._forgetChildrenRecursive = function(parentElement) { var child = parentElement.children[0]; while (child) { this._forgetTreeElement(child); child = child.traverseNextTreeElement(false, parentElement, true); } } TreeOutline.prototype.getCachedTreeElement = function(representedObject) { if (!representedObject) return null; var elements = this._treeElementsMap.get(representedObject); if (elements && elements.length) return elements[0]; return null; } TreeOutline.prototype.findTreeElement = function(representedObject, isAncestor, getParent) { if (!representedObject) return null; var cachedElement = this.getCachedTreeElement(representedObject); if (cachedElement) return cachedElement; var item; var found = false; for (var i = 0; i < this.children.length; ++i) { item = this.children[i]; if (item.representedObject === representedObject || isAncestor(item.representedObject, representedObject)) { found = true; break; } } if (!found) return null; var ancestors = []; var currentObject = representedObject; while (currentObject) { ancestors.unshift(currentObject); if (currentObject === item.representedObject) break; currentObject = getParent(currentObject); } for (var i = 0; i < ancestors.length; ++i) { if (ancestors[i] === representedObject) continue; item = this.findTreeElement(ancestors[i], isAncestor, getParent); if (item) item.onpopulate(); } return this.getCachedTreeElement(representedObject); } TreeOutline.prototype.treeElementFromPoint = function(x, y) { var node = this._childrenListNode.ownerDocument.elementFromPoint(x, y); if (!node) return null; var listNode = node.enclosingNodeOrSelfWithNodeNameInArray(["ol", "li"]); if (listNode) return listNode.parentTreeElement || listNode.treeElement; return null; } TreeOutline.prototype._treeKeyPress = function(event) { if (!this.searchable || WebInspector.isBeingEdited(this._childrenListNode)) return; var searchText = String.fromCharCode(event.charCode); if (searchText.trim() !== searchText) return; this._startSearch(searchText); event.consume(true); } TreeOutline.prototype._treeKeyDown = function(event) { if (event.target !== this._childrenListNode) return; if (!this.selectedTreeElement || event.shiftKey || event.metaKey || event.ctrlKey) return; var handled = false; var nextSelectedElement; if (event.keyIdentifier === "Up" && !event.altKey) { nextSelectedElement = this.selectedTreeElement.traversePreviousTreeElement(true); while (nextSelectedElement && !nextSelectedElement.selectable) nextSelectedElement = nextSelectedElement.traversePreviousTreeElement(!this.expandTreeElementsWhenArrowing); handled = nextSelectedElement ? true : false; } else if (event.keyIdentifier === "Down" && !event.altKey) { nextSelectedElement = this.selectedTreeElement.traverseNextTreeElement(true); while (nextSelectedElement && !nextSelectedElement.selectable) nextSelectedElement = nextSelectedElement.traverseNextTreeElement(!this.expandTreeElementsWhenArrowing); handled = nextSelectedElement ? true : false; } else if (event.keyIdentifier === "Left") { if (this.selectedTreeElement.expanded) { if (event.altKey) this.selectedTreeElement.collapseRecursively(); else this.selectedTreeElement.collapse(); handled = true; } else if (this.selectedTreeElement.parent && !this.selectedTreeElement.parent.root) { handled = true; if (this.selectedTreeElement.parent.selectable) { nextSelectedElement = this.selectedTreeElement.parent; while (nextSelectedElement && !nextSelectedElement.selectable) nextSelectedElement = nextSelectedElement.parent; handled = nextSelectedElement ? true : false; } else if (this.selectedTreeElement.parent) this.selectedTreeElement.parent.collapse(); } } else if (event.keyIdentifier === "Right") { if (!this.selectedTreeElement.revealed()) { this.selectedTreeElement.reveal(); handled = true; } else if (this.selectedTreeElement.hasChildren) { handled = true; if (this.selectedTreeElement.expanded) { nextSelectedElement = this.selectedTreeElement.children[0]; while (nextSelectedElement && !nextSelectedElement.selectable) nextSelectedElement = nextSelectedElement.nextSibling; handled = nextSelectedElement ? true : false; } else { if (event.altKey) this.selectedTreeElement.expandRecursively(); else this.selectedTreeElement.expand(); } } } else if (event.keyCode === 8 || event.keyCode === 46 ) handled = this.selectedTreeElement.ondelete(); else if (isEnterKey(event)) handled = this.selectedTreeElement.onenter(); else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Space.code) handled = this.selectedTreeElement.onspace(); if (nextSelectedElement) { nextSelectedElement.reveal(); nextSelectedElement.select(false, true); } if (handled) event.consume(true); } TreeOutline.prototype.expand = function() { } TreeOutline.prototype.collapse = function() { } TreeOutline.prototype.revealed = function() { return true; } TreeOutline.prototype.reveal = function() { } TreeOutline.prototype.select = function() { } TreeOutline.prototype.revealAndSelect = function(omitFocus) { } TreeOutline.prototype._startSearch = function(searchText) { if (!this.searchInputElement || !this.searchable) return; this._searching = true; if (this.searchStarted) this.searchStarted(); this.searchInputElement.value = searchText; function focusSearchInput() { this.searchInputElement.focus(); } window.setTimeout(focusSearchInput.bind(this), 0); this._searchTextChanged(); this._boundSearchTextChanged = this._searchTextChanged.bind(this); this.searchInputElement.addEventListener("paste", this._boundSearchTextChanged); this.searchInputElement.addEventListener("cut", this._boundSearchTextChanged); this.searchInputElement.addEventListener("keypress", this._boundSearchTextChanged); this._boundSearchInputKeyDown = this._searchInputKeyDown.bind(this); this.searchInputElement.addEventListener("keydown", this._boundSearchInputKeyDown); this._boundSearchInputBlur = this._searchInputBlur.bind(this); this.searchInputElement.addEventListener("blur", this._boundSearchInputBlur); } TreeOutline.prototype._searchTextChanged = function() { function updateSearch() { var nextSelectedElement = this._nextSearchMatch(this.searchInputElement.value, this.selectedTreeElement, false); if (!nextSelectedElement) nextSelectedElement = this._nextSearchMatch(this.searchInputElement.value, this.children[0], false); this._showSearchMatchElement(nextSelectedElement); } window.setTimeout(updateSearch.bind(this), 0); } TreeOutline.prototype._showSearchMatchElement = function(treeElement) { this._currentSearchMatchElement = treeElement; if (treeElement) { this._childrenListNode.classList.add("search-match-found"); this._childrenListNode.classList.remove("search-match-not-found"); treeElement.revealAndSelect(true); } else { this._childrenListNode.classList.remove("search-match-found"); this._childrenListNode.classList.add("search-match-not-found"); } } TreeOutline.prototype._searchInputKeyDown = function(event) { if (event.shiftKey || event.metaKey || event.ctrlKey || event.altKey) return; var handled = false; var nextSelectedElement; if (event.keyIdentifier === "Down") { nextSelectedElement = this._nextSearchMatch(this.searchInputElement.value, this.selectedTreeElement, true); handled = true; } else if (event.keyIdentifier === "Up") { nextSelectedElement = this._previousSearchMatch(this.searchInputElement.value, this.selectedTreeElement); handled = true; } else if (event.keyCode === 27 ) { this._searchFinished(); handled = true; } else if (isEnterKey(event)) { var lastSearchMatchElement = this._currentSearchMatchElement; this._searchFinished(); lastSearchMatchElement.onenter(); handled = true; } if (nextSelectedElement) this._showSearchMatchElement(nextSelectedElement); if (handled) event.consume(true); else window.setTimeout(this._boundSearchTextChanged, 0); } TreeOutline.prototype._nextSearchMatch = function(searchText, startTreeElement, skipStartTreeElement) { var currentTreeElement = startTreeElement; var skipCurrentTreeElement = skipStartTreeElement; while (currentTreeElement && (skipCurrentTreeElement || !currentTreeElement.matchesSearchText || !currentTreeElement.matchesSearchText(searchText))) { currentTreeElement = currentTreeElement.traverseNextTreeElement(true, null, true); skipCurrentTreeElement = false; } return currentTreeElement; } TreeOutline.prototype._previousSearchMatch = function(searchText, startTreeElement) { var currentTreeElement = startTreeElement; var skipCurrentTreeElement = true; while (currentTreeElement && (skipCurrentTreeElement || !currentTreeElement.matchesSearchText || !currentTreeElement.matchesSearchText(searchText))) { currentTreeElement = currentTreeElement.traversePreviousTreeElement(true, true); skipCurrentTreeElement = false; } return currentTreeElement; } TreeOutline.prototype._searchInputBlur = function(event) { this._searchFinished(); } TreeOutline.prototype._searchFinished = function() { if (!this._searching) return; delete this._searching; this._childrenListNode.classList.remove("search-match-found"); this._childrenListNode.classList.remove("search-match-not-found"); delete this._currentSearchMatchElement; this.searchInputElement.value = ""; this.searchInputElement.removeEventListener("paste", this._boundSearchTextChanged); this.searchInputElement.removeEventListener("cut", this._boundSearchTextChanged); delete this._boundSearchTextChanged; this.searchInputElement.removeEventListener("keydown", this._boundSearchInputKeyDown); delete this._boundSearchInputKeyDown; this.searchInputElement.removeEventListener("blur", this._boundSearchInputBlur); delete this._boundSearchInputBlur; if (this.searchFinished) this.searchFinished(); this.treeOutline._childrenListNode.focus(); } TreeOutline.prototype.stopSearch = function() { this._searchFinished(); } function TreeElement(title, representedObject, hasChildren) { this._title = title; this.representedObject = (representedObject || {}); this._hidden = false; this._selectable = true; this.expanded = false; this.selected = false; this.hasChildren = hasChildren; this.children = []; this.treeOutline = null; this.parent = null; this.previousSibling = null; this.nextSibling = null; this._listItemNode = null; } TreeElement.prototype = { arrowToggleWidth: 10, get selectable() { if (this._hidden) return false; return this._selectable; }, set selectable(x) { this._selectable = x; }, get listItemElement() { return this._listItemNode; }, get childrenListElement() { return this._childrenListNode; }, get title() { return this._title; }, set title(x) { this._title = x; this._setListItemNodeContent(); }, get tooltip() { return this._tooltip; }, set tooltip(x) { this._tooltip = x; if (this._listItemNode) this._listItemNode.title = x ? x : ""; }, get hasChildren() { return this._hasChildren; }, set hasChildren(x) { if (this._hasChildren === x) return; this._hasChildren = x; if (!this._listItemNode) return; if (x) this._listItemNode.classList.add("parent"); else { this._listItemNode.classList.remove("parent"); this.collapse(); } }, get hidden() { return this._hidden; }, set hidden(x) { if (this._hidden === x) return; this._hidden = x; if (x) { if (this._listItemNode) this._listItemNode.classList.add("hidden"); if (this._childrenListNode) this._childrenListNode.classList.add("hidden"); } else { if (this._listItemNode) this._listItemNode.classList.remove("hidden"); if (this._childrenListNode) this._childrenListNode.classList.remove("hidden"); } }, get shouldRefreshChildren() { return this._shouldRefreshChildren; }, set shouldRefreshChildren(x) { this._shouldRefreshChildren = x; if (x && this.expanded) this.expand(); }, _setListItemNodeContent: function() { if (!this._listItemNode) return; if (typeof this._title === "string") this._listItemNode.textContent = this._title; else { this._listItemNode.removeChildren(); if (this._title) this._listItemNode.appendChild(this._title); } } } TreeElement.prototype.appendChild = TreeOutline.prototype.appendChild; TreeElement.prototype.insertChild = TreeOutline.prototype.insertChild; TreeElement.prototype.removeChild = TreeOutline.prototype.removeChild; TreeElement.prototype.removeChildAtIndex = TreeOutline.prototype.removeChildAtIndex; TreeElement.prototype.removeChildren = TreeOutline.prototype.removeChildren; TreeElement.prototype._attach = function() { if (!this._listItemNode || this.parent._shouldRefreshChildren) { if (this._listItemNode && this._listItemNode.parentNode) this._listItemNode.parentNode.removeChild(this._listItemNode); this._listItemNode = this.treeOutline._childrenListNode.ownerDocument.createElement("li"); this._listItemNode.treeElement = this; this._setListItemNodeContent(); this._listItemNode.title = this._tooltip ? this._tooltip : ""; if (this.hidden) this._listItemNode.classList.add("hidden"); if (this.hasChildren) this._listItemNode.classList.add("parent"); if (this.expanded) this._listItemNode.classList.add("expanded"); if (this.selected) this._listItemNode.classList.add("selected"); this._listItemNode.addEventListener("mousedown", TreeElement.treeElementMouseDown, false); this._listItemNode.addEventListener("click", TreeElement.treeElementToggled, false); this._listItemNode.addEventListener("dblclick", TreeElement.treeElementDoubleClicked, false); this.onattach(); } var nextSibling = null; if (this.nextSibling && this.nextSibling._listItemNode && this.nextSibling._listItemNode.parentNode === this.parent._childrenListNode) nextSibling = this.nextSibling._listItemNode; this.parent._childrenListNode.insertBefore(this._listItemNode, nextSibling); if (this._childrenListNode) this.parent._childrenListNode.insertBefore(this._childrenListNode, this._listItemNode.nextSibling); if (this.selected) this.select(); if (this.expanded) this.expand(); } TreeElement.prototype._detach = function() { if (this._listItemNode && this._listItemNode.parentNode) this._listItemNode.parentNode.removeChild(this._listItemNode); if (this._childrenListNode && this._childrenListNode.parentNode) this._childrenListNode.parentNode.removeChild(this._childrenListNode); } TreeElement.treeElementMouseDown = function(event) { var element = event.currentTarget; if (!element || !element.treeElement || !element.treeElement.selectable) return; if (element.treeElement.isEventWithinDisclosureTriangle(event)) return; element.treeElement.selectOnMouseDown(event); } TreeElement.treeElementToggled = function(event) { var element = event.currentTarget; if (!element || !element.treeElement) return; var toggleOnClick = element.treeElement.toggleOnClick && !element.treeElement.selectable; var isInTriangle = element.treeElement.isEventWithinDisclosureTriangle(event); if (!toggleOnClick && !isInTriangle) return; if (element.treeElement.expanded) { if (event.altKey) element.treeElement.collapseRecursively(); else element.treeElement.collapse(); } else { if (event.altKey) element.treeElement.expandRecursively(); else element.treeElement.expand(); } event.consume(); } TreeElement.treeElementDoubleClicked = function(event) { var element = event.currentTarget; if (!element || !element.treeElement) return; var handled = element.treeElement.ondblclick.call(element.treeElement, event); if (handled) return; if (element.treeElement.hasChildren && !element.treeElement.expanded) element.treeElement.expand(); } TreeElement.prototype.collapse = function() { if (this._listItemNode) this._listItemNode.classList.remove("expanded"); if (this._childrenListNode) this._childrenListNode.classList.remove("expanded"); this.expanded = false; if (this.treeOutline) this.treeOutline._expandedStateMap.put(this.representedObject, false); this.oncollapse(); } TreeElement.prototype.collapseRecursively = function() { var item = this; while (item) { if (item.expanded) item.collapse(); item = item.traverseNextTreeElement(false, this, true); } } TreeElement.prototype.expand = function() { if (!this.hasChildren || (this.expanded && !this._shouldRefreshChildren && this._childrenListNode)) return; this.expanded = true; if (this.treeOutline) this.treeOutline._expandedStateMap.put(this.representedObject, true); if (this.treeOutline && (!this._childrenListNode || this._shouldRefreshChildren)) { if (this._childrenListNode && this._childrenListNode.parentNode) this._childrenListNode.parentNode.removeChild(this._childrenListNode); this._childrenListNode = this.treeOutline._childrenListNode.ownerDocument.createElement("ol"); this._childrenListNode.parentTreeElement = this; this._childrenListNode.classList.add("children"); if (this.hidden) this._childrenListNode.classList.add("hidden"); this.onpopulate(); for (var i = 0; i < this.children.length; ++i) this.children[i]._attach(); delete this._shouldRefreshChildren; } if (this._listItemNode) { this._listItemNode.classList.add("expanded"); if (this._childrenListNode && this._childrenListNode.parentNode != this._listItemNode.parentNode) this.parent._childrenListNode.insertBefore(this._childrenListNode, this._listItemNode.nextSibling); } if (this._childrenListNode) this._childrenListNode.classList.add("expanded"); this.onexpand(); } TreeElement.prototype.expandRecursively = function(maxDepth) { var item = this; var info = {}; var depth = 0; if (isNaN(maxDepth)) maxDepth = 3; while (item) { if (depth < maxDepth) item.expand(); item = item.traverseNextTreeElement(false, this, (depth >= maxDepth), info); depth += info.depthChange; } } TreeElement.prototype.hasAncestor = function(ancestor) { if (!ancestor) return false; var currentNode = this.parent; while (currentNode) { if (ancestor === currentNode) return true; currentNode = currentNode.parent; } return false; } TreeElement.prototype.reveal = function() { var currentAncestor = this.parent; while (currentAncestor && !currentAncestor.root) { if (!currentAncestor.expanded) currentAncestor.expand(); currentAncestor = currentAncestor.parent; } this.onreveal(this); } TreeElement.prototype.revealed = function() { var currentAncestor = this.parent; while (currentAncestor && !currentAncestor.root) { if (!currentAncestor.expanded) return false; currentAncestor = currentAncestor.parent; } return true; } TreeElement.prototype.selectOnMouseDown = function(event) { if (this.select(false, true)) event.consume(true); } TreeElement.prototype.select = function(omitFocus, selectedByUser) { if (!this.treeOutline || !this.selectable || this.selected) return false; if (this.treeOutline.selectedTreeElement) this.treeOutline.selectedTreeElement.deselect(); this.selected = true; if(!omitFocus) this.treeOutline._childrenListNode.focus(); if (!this.treeOutline) return false; this.treeOutline.selectedTreeElement = this; if (this._listItemNode) this._listItemNode.classList.add("selected"); return this.onselect(selectedByUser); } TreeElement.prototype.revealAndSelect = function(omitFocus) { this.reveal(); this.select(omitFocus); } TreeElement.prototype.deselect = function(supressOnDeselect) { if (!this.treeOutline || this.treeOutline.selectedTreeElement !== this || !this.selected) return false; this.selected = false; this.treeOutline.selectedTreeElement = null; if (this._listItemNode) this._listItemNode.classList.remove("selected"); return true; } TreeElement.prototype.onpopulate = function() { } TreeElement.prototype.onenter = function() { } TreeElement.prototype.ondelete = function() { } TreeElement.prototype.onspace = function() { } TreeElement.prototype.onattach = function() { } TreeElement.prototype.onexpand = function() { } TreeElement.prototype.oncollapse = function() { } TreeElement.prototype.ondblclick = function() { } TreeElement.prototype.onreveal = function() { } TreeElement.prototype.onselect = function(selectedByUser) { } TreeElement.prototype.traverseNextTreeElement = function(skipUnrevealed, stayWithin, dontPopulate, info) { if (!dontPopulate && this.hasChildren) this.onpopulate(); if (info) info.depthChange = 0; var element = skipUnrevealed ? (this.revealed() ? this.children[0] : null) : this.children[0]; if (element && (!skipUnrevealed || (skipUnrevealed && this.expanded))) { if (info) info.depthChange = 1; return element; } if (this === stayWithin) return null; element = skipUnrevealed ? (this.revealed() ? this.nextSibling : null) : this.nextSibling; if (element) return element; element = this; while (element && !element.root && !(skipUnrevealed ? (element.revealed() ? element.nextSibling : null) : element.nextSibling) && element.parent !== stayWithin) { if (info) info.depthChange -= 1; element = element.parent; } if (!element) return null; return (skipUnrevealed ? (element.revealed() ? element.nextSibling : null) : element.nextSibling); } TreeElement.prototype.traversePreviousTreeElement = function(skipUnrevealed, dontPopulate) { var element = skipUnrevealed ? (this.revealed() ? this.previousSibling : null) : this.previousSibling; if (!dontPopulate && element && element.hasChildren) element.onpopulate(); while (element && (skipUnrevealed ? (element.revealed() && element.expanded ? element.children[element.children.length - 1] : null) : element.children[element.children.length - 1])) { if (!dontPopulate && element.hasChildren) element.onpopulate(); element = (skipUnrevealed ? (element.revealed() && element.expanded ? element.children[element.children.length - 1] : null) : element.children[element.children.length - 1]); } if (element) return element; if (!this.parent || this.parent.root) return null; return this.parent; } TreeElement.prototype.isEventWithinDisclosureTriangle = function(event) { var paddingLeftValue = window.getComputedStyle(this._listItemNode).getPropertyCSSValue("padding-left"); var computedLeftPadding = paddingLeftValue ? paddingLeftValue.getFloatValue(CSSPrimitiveValue.CSS_PX) : 0; var left = this._listItemNode.totalOffsetLeft() + computedLeftPadding; return event.pageX >= left && event.pageX <= left + this.arrowToggleWidth && this.hasChildren; } var WebInspector = { _panelDescriptors: function() { this.panels = {}; WebInspector.inspectorView = new WebInspector.InspectorView(); var parentElement = document.getElementById("main"); WebInspector.inspectorView.show(parentElement); WebInspector.inspectorView.addEventListener(WebInspector.InspectorView.Events.PanelSelected, this._panelSelected, this); var elements = new WebInspector.ElementsPanelDescriptor(); var resources = new WebInspector.PanelDescriptor("resources", WebInspector.UIString("Resources"), "ResourcesPanel", "ResourcesPanel.js"); var network = new WebInspector.NetworkPanelDescriptor(); var scripts = new WebInspector.ScriptsPanelDescriptor(); var timeline = new WebInspector.PanelDescriptor("timeline", WebInspector.UIString("Timeline"), "TimelinePanel", "TimelinePanel.js"); var profiles = new WebInspector.PanelDescriptor("profiles", WebInspector.UIString("Profiles"), "ProfilesPanel", "ProfilesPanel.js"); var audits = new WebInspector.PanelDescriptor("audits", WebInspector.UIString("Audits"), "AuditsPanel", "AuditsPanel.js"); var console = new WebInspector.PanelDescriptor("console", WebInspector.UIString("Console"), "ConsolePanel"); var allDescriptors = [elements, resources, network, scripts, timeline, profiles, audits, console]; var panelDescriptors = []; if (WebInspector.WorkerManager.isWorkerFrontend()) { panelDescriptors.push(scripts); panelDescriptors.push(timeline); panelDescriptors.push(profiles); panelDescriptors.push(console); return panelDescriptors; } var allDescriptors = [elements, resources, network, scripts, timeline, profiles, audits, console]; var hiddenPanels = InspectorFrontendHost.hiddenPanels(); for (var i = 0; i < allDescriptors.length; ++i) { if (hiddenPanels.indexOf(allDescriptors[i].name()) === -1) panelDescriptors.push(allDescriptors[i]); } return panelDescriptors; }, _panelSelected: function() { this._toggleConsoleButton.disabled = WebInspector.inspectorView.currentPanel().name === "console"; }, _createGlobalStatusBarItems: function() { var bottomStatusBarContainer = document.getElementById("bottom-status-bar-container"); var mainStatusBar = document.getElementById("main-status-bar"); mainStatusBar.insertBefore(this.dockController.element, bottomStatusBarContainer); this._toggleConsoleButton = new WebInspector.StatusBarButton(WebInspector.UIString("Show console."), "console-status-bar-item"); this._toggleConsoleButton.addEventListener("click", this._toggleConsoleButtonClicked.bind(this), false); mainStatusBar.insertBefore(this._toggleConsoleButton.element, bottomStatusBarContainer); if (!WebInspector.WorkerManager.isWorkerFrontend()) { this._nodeSearchButton = new WebInspector.StatusBarButton(WebInspector.UIString("Select an element in the page to inspect it."), "node-search-status-bar-item"); this._nodeSearchButton.addEventListener("click", this.toggleSearchingForNode, this); mainStatusBar.insertBefore(this._nodeSearchButton.element, bottomStatusBarContainer); } mainStatusBar.appendChild(this.settingsController.statusBarItem); }, _toggleConsoleButtonClicked: function() { if (this._toggleConsoleButton.disabled) return; this._toggleConsoleButton.toggled = !this._toggleConsoleButton.toggled; var animationType = window.event && window.event.shiftKey ? WebInspector.Drawer.AnimationType.Slow : WebInspector.Drawer.AnimationType.Normal; if (this._toggleConsoleButton.toggled) { this._toggleConsoleButton.title = WebInspector.UIString("Hide console."); this.drawer.show(this.consoleView, animationType); this._consoleWasShown = true; } else { this._toggleConsoleButton.title = WebInspector.UIString("Show console."); this.drawer.hide(animationType); delete this._consoleWasShown; } }, showViewInDrawer: function(statusBarElement, view, onclose) { this._toggleConsoleButton.title = WebInspector.UIString("Hide console."); this._toggleConsoleButton.toggled = false; this._closePreviousDrawerView(); var drawerStatusBarHeader = document.createElement("div"); drawerStatusBarHeader.className = "drawer-header status-bar-item"; drawerStatusBarHeader.appendChild(statusBarElement); drawerStatusBarHeader.onclose = onclose; var closeButton = drawerStatusBarHeader.createChild("span"); closeButton.textContent = WebInspector.UIString("\u00D7"); closeButton.addStyleClass("drawer-header-close-button"); closeButton.addEventListener("click", this.closeViewInDrawer.bind(this), false); document.getElementById("panel-status-bar").firstElementChild.appendChild(drawerStatusBarHeader); this._drawerStatusBarHeader = drawerStatusBarHeader; this.drawer.show(view, WebInspector.Drawer.AnimationType.Immediately); }, closeViewInDrawer: function() { if (this._drawerStatusBarHeader) { this._closePreviousDrawerView(); if (!this._consoleWasShown) this.drawer.hide(WebInspector.Drawer.AnimationType.Immediately); else this._toggleConsoleButtonClicked(); } }, _closePreviousDrawerView: function() { if (this._drawerStatusBarHeader) { this._drawerStatusBarHeader.parentElement.removeChild(this._drawerStatusBarHeader); if (this._drawerStatusBarHeader.onclose) this._drawerStatusBarHeader.onclose(); delete this._drawerStatusBarHeader; } }, _updateErrorAndWarningCounts: function() { var errorWarningElement = document.getElementById("error-warning-count"); if (!errorWarningElement) return; var errors = WebInspector.console.errors; var warnings = WebInspector.console.warnings; if (!errors && !warnings) { errorWarningElement.addStyleClass("hidden"); return; } errorWarningElement.removeStyleClass("hidden"); errorWarningElement.removeChildren(); if (errors) { var errorImageElement = document.createElement("img"); errorImageElement.id = "error-count-img"; errorWarningElement.appendChild(errorImageElement); var errorElement = document.createElement("span"); errorElement.id = "error-count"; errorElement.textContent = errors; errorWarningElement.appendChild(errorElement); } if (warnings) { var warningsImageElement = document.createElement("img"); warningsImageElement.id = "warning-count-img"; errorWarningElement.appendChild(warningsImageElement); var warningsElement = document.createElement("span"); warningsElement.id = "warning-count"; warningsElement.textContent = warnings; errorWarningElement.appendChild(warningsElement); } if (errors) { if (warnings) { if (errors == 1) { if (warnings == 1) errorWarningElement.title = WebInspector.UIString("%d error, %d warning", errors, warnings); else errorWarningElement.title = WebInspector.UIString("%d error, %d warnings", errors, warnings); } else if (warnings == 1) errorWarningElement.title = WebInspector.UIString("%d errors, %d warning", errors, warnings); else errorWarningElement.title = WebInspector.UIString("%d errors, %d warnings", errors, warnings); } else if (errors == 1) errorWarningElement.title = WebInspector.UIString("%d error", errors); else errorWarningElement.title = WebInspector.UIString("%d errors", errors); } else if (warnings == 1) errorWarningElement.title = WebInspector.UIString("%d warning", warnings); else if (warnings) errorWarningElement.title = WebInspector.UIString("%d warnings", warnings); else errorWarningElement.title = null; }, get inspectedPageDomain() { var parsedURL = WebInspector.inspectedPageURL && WebInspector.inspectedPageURL.asParsedURL(); return parsedURL ? parsedURL.host : ""; }, _initializeCapability: function(name, callback, error, result) { Capabilities[name] = result; if (callback) callback(); }, _zoomIn: function() { this._zoomLevel = Math.min(this._zoomLevel + 1, WebInspector.Zoom.Table.length - WebInspector.Zoom.DefaultOffset - 1); this._requestZoom(); }, _zoomOut: function() { this._zoomLevel = Math.max(this._zoomLevel - 1, -WebInspector.Zoom.DefaultOffset); this._requestZoom(); }, _resetZoom: function() { this._zoomLevel = 0; this._requestZoom(); }, _requestZoom: function() { WebInspector.settings.zoomLevel.set(this._zoomLevel); var index = this._zoomLevel + WebInspector.Zoom.DefaultOffset; index = Math.min(WebInspector.Zoom.Table.length - 1, index); index = Math.max(0, index); InspectorFrontendHost.setZoomFactor(WebInspector.Zoom.Table[index]); }, toggleSearchingForNode: function() { var enabled = !this._nodeSearchButton.toggled; function callback(error) { if (!error) this._nodeSearchButton.toggled = enabled; } WebInspector.domAgent.setInspectModeEnabled(enabled, callback.bind(this)); }, _profilesLinkifier: function(title) { var profileStringMatches = WebInspector.ProfileURLRegExp.exec(title); if (profileStringMatches) { var profilesPanel = WebInspector.panel("profiles"); title = WebInspector.ProfilesPanel._instance.displayTitleForProfileLink(profileStringMatches[2], profileStringMatches[1]); } return title; }, _debuggerPaused: function() { WebInspector.panel("scripts"); } } WebInspector.Events = { InspectorClosing: "InspectorClosing" } {(function parseQueryParameters() { WebInspector.queryParamsObject = {}; var queryParams = window.location.search; if (!queryParams) return; var params = queryParams.substring(1).split("&"); for (var i = 0; i < params.length; ++i) { var pair = params[i].split("="); WebInspector.queryParamsObject[pair[0]] = pair[1]; } })();} WebInspector.loaded = function() { InspectorBackend.loadFromJSONIfNeeded("../Inspector.json"); WebInspector.dockController = new WebInspector.DockController(); if (WebInspector.WorkerManager.isDedicatedWorkerFrontend()) { WebInspector.doLoadedDone(); return; } var ws; if ("ws" in WebInspector.queryParamsObject) ws = "ws://" + WebInspector.queryParamsObject.ws; else if ("page" in WebInspector.queryParamsObject) { var page = WebInspector.queryParamsObject.page; var host = "host" in WebInspector.queryParamsObject ? WebInspector.queryParamsObject.host : window.location.host; ws = "ws://" + host + "/devtools/page/" + page; } if (ws) { WebInspector.socket = new WebSocket(ws); WebInspector.socket.onmessage = function(message) { InspectorBackend.dispatch(message.data); } WebInspector.socket.onerror = function(error) { console.error(error); } WebInspector.socket.onopen = function() { InspectorFrontendHost.sendMessageToBackend = WebInspector.socket.send.bind(WebInspector.socket); WebInspector.doLoadedDone(); } WebInspector.socket.onclose = function() { if (!WebInspector.socket._detachReason) (new WebInspector.RemoteDebuggingTerminatedScreen("websocket_closed")).showModal(); } return; } WebInspector.doLoadedDone(); if (InspectorFrontendHost.isStub) { InspectorFrontendAPI.dispatchQueryParameters(); WebInspector._doLoadedDoneWithCapabilities(); } } WebInspector.doLoadedDone = function() { WebInspector.installPortStyles(); if (WebInspector.socket) document.body.addStyleClass("remote"); if (WebInspector.queryParamsObject.toolbarColor && WebInspector.queryParamsObject.textColor) WebInspector.setToolbarColors(WebInspector.queryParamsObject.toolbarColor, WebInspector.queryParamsObject.textColor); InspectorFrontendHost.loaded(); WebInspector.WorkerManager.loaded(); DebuggerAgent.causesRecompilation(WebInspector._initializeCapability.bind(WebInspector, "debuggerCausesRecompilation", null)); DebuggerAgent.supportsSeparateScriptCompilationAndExecution(WebInspector._initializeCapability.bind(WebInspector, "separateScriptCompilationAndExecutionEnabled", null)); ProfilerAgent.causesRecompilation(WebInspector._initializeCapability.bind(WebInspector, "profilerCausesRecompilation", null)); ProfilerAgent.isSampling(WebInspector._initializeCapability.bind(WebInspector, "samplingCPUProfiler", null)); ProfilerAgent.hasHeapProfiler(WebInspector._initializeCapability.bind(WebInspector, "heapProfilerPresent", null)); TimelineAgent.supportsFrameInstrumentation(WebInspector._initializeCapability.bind(WebInspector, "timelineSupportsFrameInstrumentation", null)); TimelineAgent.canMonitorMainThread(WebInspector._initializeCapability.bind(WebInspector, "timelineCanMonitorMainThread", null)); PageAgent.canOverrideDeviceMetrics(WebInspector._initializeCapability.bind(WebInspector, "canOverrideDeviceMetrics", null)); PageAgent.canOverrideGeolocation(WebInspector._initializeCapability.bind(WebInspector, "canOverrideGeolocation", null)); PageAgent.canOverrideDeviceOrientation(WebInspector._initializeCapability.bind(WebInspector, "canOverrideDeviceOrientation", WebInspector._doLoadedDoneWithCapabilities.bind(WebInspector))); } WebInspector._doLoadedDoneWithCapabilities = function() { WebInspector.shortcutsScreen = new WebInspector.ShortcutsScreen(); this._registerShortcuts(); WebInspector.shortcutsScreen.section(WebInspector.UIString("Console")); WebInspector.shortcutsScreen.section(WebInspector.UIString("Elements Panel")); this.console = new WebInspector.ConsoleModel(); this.console.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._updateErrorAndWarningCounts, this); this.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._updateErrorAndWarningCounts, this); this.console.addEventListener(WebInspector.ConsoleModel.Events.RepeatCountUpdated, this._updateErrorAndWarningCounts, this); WebInspector.CSSCompletions.requestCSSNameCompletions(); this.drawer = new WebInspector.Drawer(); this.networkManager = new WebInspector.NetworkManager(); this.resourceTreeModel = new WebInspector.ResourceTreeModel(this.networkManager); this.debuggerModel = new WebInspector.DebuggerModel(); this.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this); this.networkLog = new WebInspector.NetworkLog(); this.domAgent = new WebInspector.DOMAgent(); this.runtimeModel = new WebInspector.RuntimeModel(this.resourceTreeModel); this.consoleView = new WebInspector.ConsoleView(WebInspector.WorkerManager.isWorkerFrontend()); InspectorBackend.registerInspectorDispatcher(this); this.cssModel = new WebInspector.CSSStyleModel(); this.timelineManager = new WebInspector.TimelineManager(); this.userAgentSupport = new WebInspector.UserAgentSupport(); this.searchController = new WebInspector.SearchController(); this.advancedSearchController = new WebInspector.AdvancedSearchController(); this.settingsController = new WebInspector.SettingsController(); this.domBreakpointsSidebarPane = new WebInspector.DOMBreakpointsSidebarPane(); this._zoomLevel = WebInspector.settings.zoomLevel.get(); if (this._zoomLevel) this._requestZoom(); var autoselectPanel = WebInspector.UIString("a panel chosen automatically"); var openAnchorLocationSetting = WebInspector.settings.createSetting("openLinkHandler", autoselectPanel); this.openAnchorLocationRegistry = new WebInspector.HandlerRegistry(openAnchorLocationSetting); this.openAnchorLocationRegistry.registerHandler(autoselectPanel, function() { return false; }); this.networkWorkspaceProvider = new WebInspector.NetworkWorkspaceProvider(); this.workspace = new WebInspector.Workspace(); this.workspace.addProject("network", this.networkWorkspaceProvider); this.workspaceController = new WebInspector.WorkspaceController(this.workspace); this.breakpointManager = new WebInspector.BreakpointManager(WebInspector.settings.breakpoints, this.debuggerModel, this.workspace); this.scriptSnippetModel = new WebInspector.ScriptSnippetModel(this.workspace, this.networkWorkspaceProvider); new WebInspector.DebuggerScriptMapping(this.workspace, this.networkWorkspaceProvider); this.styleContentBinding = new WebInspector.StyleContentBinding(this.cssModel); new WebInspector.NetworkUISourceCodeProvider(this.workspace, this.networkWorkspaceProvider); new WebInspector.StylesSourceMapping(this.workspace); if (WebInspector.experimentsSettings.sass.isEnabled()) new WebInspector.SASSSourceMapping(this.workspace, this.networkWorkspaceProvider); new WebInspector.PresentationConsoleMessageHelper(this.workspace); this._createGlobalStatusBarItems(); this.toolbar = new WebInspector.Toolbar(); WebInspector.startBatchUpdate(); var panelDescriptors = this._panelDescriptors(); for (var i = 0; i < panelDescriptors.length; ++i) WebInspector.inspectorView.addPanel(panelDescriptors[i]); WebInspector.endBatchUpdate(); this.addMainEventListeners(document); WebInspector.registerLinkifierPlugin(this._profilesLinkifier.bind(this)); window.addEventListener("resize", this.windowResize.bind(this), true); var errorWarningCount = document.getElementById("error-warning-count"); errorWarningCount.addEventListener("click", this.showConsole.bind(this), false); this._updateErrorAndWarningCounts(); this.extensionServer.initExtensions(); this.console.enableAgent(); function showInitialPanel() { if (!WebInspector.inspectorView.currentPanel()) WebInspector.showPanel(WebInspector.settings.lastActivePanel.get()); } InspectorAgent.enable(showInitialPanel); this.databaseModel = new WebInspector.DatabaseModel(); this.domStorageModel = new WebInspector.DOMStorageModel(); if (!Capabilities.profilerCausesRecompilation || WebInspector.settings.profilerEnabled.get()) ProfilerAgent.enable(); if (WebInspector.settings.showPaintRects.get()) PageAgent.setShowPaintRects(true); if (WebInspector.settings.javaScriptDisabled.get()) PageAgent.setScriptExecutionDisabled(true); this.domAgent._emulateTouchEventsChanged(); WebInspector.WorkerManager.loadCompleted(); InspectorFrontendAPI.loadCompleted(); } var windowLoaded = function() { var localizedStringsURL = InspectorFrontendHost.localizedStringsURL(); if (localizedStringsURL) { var localizedStringsScriptElement = document.createElement("script"); localizedStringsScriptElement.addEventListener("load", WebInspector.loaded.bind(WebInspector), false); localizedStringsScriptElement.type = "text/javascript"; localizedStringsScriptElement.src = localizedStringsURL; document.head.appendChild(localizedStringsScriptElement); } else WebInspector.loaded(); window.removeEventListener("DOMContentLoaded", windowLoaded, false); delete windowLoaded; }; window.addEventListener("DOMContentLoaded", windowLoaded, false); var messagesToDispatch = []; WebInspector.dispatchQueueIsEmpty = function() { return messagesToDispatch.length == 0; } WebInspector.dispatch = function(message) { messagesToDispatch.push(message); setTimeout(function() { InspectorBackend.dispatch(messagesToDispatch.shift()); }, 0); } WebInspector.windowResize = function(event) { if (WebInspector.inspectorView) WebInspector.inspectorView.doResize(); if (WebInspector.drawer) WebInspector.drawer.resize(); if (WebInspector.toolbar) WebInspector.toolbar.resize(); if (WebInspector.settingsController) WebInspector.settingsController.resize(); } WebInspector.setDockingUnavailable = function(unavailable) { if (this.dockController) this.dockController.setDockingUnavailable(unavailable); } WebInspector.close = function(event) { if (this._isClosing) return; this._isClosing = true; this.notifications.dispatchEventToListeners(WebInspector.Events.InspectorClosing); InspectorFrontendHost.closeWindow(); } WebInspector.documentClick = function(event) { var anchor = event.target.enclosingNodeOrSelfWithNodeName("a"); if (!anchor || anchor.target === "_blank") return; event.consume(true); function followLink() { if (WebInspector.isBeingEdited(event.target) || WebInspector._showAnchorLocation(anchor)) return; const profileMatch = WebInspector.ProfileURLRegExp.exec(anchor.href); if (profileMatch) { WebInspector.showProfileForURL(anchor.href); return; } var parsedURL = anchor.href.asParsedURL(); if (parsedURL && parsedURL.scheme === "webkit-link-action") { if (parsedURL.host === "show-panel") { var panel = parsedURL.path.substring(1); if (WebInspector.panel(panel)) WebInspector.showPanel(panel); } return; } InspectorFrontendHost.openInNewTab(anchor.href); } if (WebInspector.followLinkTimeout) clearTimeout(WebInspector.followLinkTimeout); if (anchor.preventFollowOnDoubleClick) { if (event.detail === 1) WebInspector.followLinkTimeout = setTimeout(followLink, 333); return; } followLink(); } WebInspector.openResource = function(resourceURL, inResourcesPanel) { var resource = WebInspector.resourceForURL(resourceURL); if (inResourcesPanel && resource) WebInspector.showPanel("resources").showResource(resource); else InspectorFrontendHost.openInNewTab(resourceURL); } WebInspector._registerShortcuts = function() { var shortcut = WebInspector.KeyboardShortcut; var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("All Panels")); var keys = [ shortcut.shortcutToString("]", shortcut.Modifiers.CtrlOrMeta), shortcut.shortcutToString("[", shortcut.Modifiers.CtrlOrMeta) ]; section.addRelatedKeys(keys, WebInspector.UIString("Go to the panel to the left/right")); var keys = [ shortcut.shortcutToString("[", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Alt), shortcut.shortcutToString("]", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Alt) ]; section.addRelatedKeys(keys, WebInspector.UIString("Go back/forward in panel history")); section.addKey(shortcut.shortcutToString(shortcut.Keys.Esc), WebInspector.UIString("Toggle console")); section.addKey(shortcut.shortcutToString("f", shortcut.Modifiers.CtrlOrMeta), WebInspector.UIString("Search")); var advancedSearchShortcut = WebInspector.AdvancedSearchController.createShortcut(); section.addKey(advancedSearchShortcut.name, WebInspector.UIString("Search across all sources")); var openResourceShortcut = WebInspector.KeyboardShortcut.makeDescriptor("o", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta); section.addKey(openResourceShortcut.name, WebInspector.UIString("Go to source")); if (WebInspector.isMac()) { keys = [ shortcut.shortcutToString("g", shortcut.Modifiers.Meta), shortcut.shortcutToString("g", shortcut.Modifiers.Meta | shortcut.Modifiers.Shift) ]; section.addRelatedKeys(keys, WebInspector.UIString("Find next/previous")); } var goToShortcut = WebInspector.GoToLineDialog.createShortcut(); section.addKey(goToShortcut.name, WebInspector.UIString("Go to line")); } WebInspector.documentKeyDown = function(event) { const helpKey = WebInspector.isMac() ? "U+003F" : "U+00BF"; if (event.keyIdentifier === "F1" || (event.keyIdentifier === helpKey && event.shiftKey && (!WebInspector.isBeingEdited(event.target) || event.metaKey))) { this.settingsController.showSettingsScreen(WebInspector.SettingsScreen.Tabs.Shortcuts); event.consume(true); return; } if (WebInspector.currentFocusElement() && WebInspector.currentFocusElement().handleKeyEvent) { WebInspector.currentFocusElement().handleKeyEvent(event); if (event.handled) { event.consume(true); return; } } if (WebInspector.inspectorView.currentPanel()) { WebInspector.inspectorView.currentPanel().handleShortcut(event); if (event.handled) { event.consume(true); return; } } if (WebInspector.searchController.handleShortcut(event)) return; if (WebInspector.advancedSearchController.handleShortcut(event)) return; switch (event.keyIdentifier) { case "U+004F": if (!event.shiftKey && !event.altKey && WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event)) { WebInspector.showPanel("scripts").showGoToSourceDialog(); event.consume(true); } break; case "U+0052": if (WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event)) { PageAgent.reload(event.shiftKey); event.consume(true); } break; case "F5": if (!WebInspector.isMac()) { PageAgent.reload(event.ctrlKey || event.shiftKey); event.consume(true); } break; } var isValidZoomShortcut = WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) && !event.altKey && !InspectorFrontendHost.isStub; switch (event.keyCode) { case 107: case 187: if (isValidZoomShortcut) { WebInspector._zoomIn(); event.consume(true); } break; case 109: case 189: if (isValidZoomShortcut) { WebInspector._zoomOut(); event.consume(true); } break; case 48: if (isValidZoomShortcut && !event.shiftKey) { WebInspector._resetZoom(); event.consume(true); } break; } if (event.keyIdentifier === "U+0043") { if (WebInspector.isMac()) var isNodeSearchKey = event.metaKey && !event.ctrlKey && !event.altKey && event.shiftKey; else var isNodeSearchKey = event.ctrlKey && !event.metaKey && !event.altKey && event.shiftKey; if (isNodeSearchKey) { this.toggleSearchingForNode(); event.consume(true); return; } return; } } WebInspector.postDocumentKeyDown = function(event) { if (event.handled) return; if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code) { if (!this._toggleConsoleButton.toggled && WebInspector.drawer.visible) this.closeViewInDrawer(); else this._toggleConsoleButtonClicked(); } } WebInspector.documentCanCopy = function(event) { if (WebInspector.inspectorView.currentPanel() && WebInspector.inspectorView.currentPanel().handleCopyEvent) event.preventDefault(); } WebInspector.documentCopy = function(event) { if (WebInspector.inspectorView.currentPanel() && WebInspector.inspectorView.currentPanel().handleCopyEvent) WebInspector.inspectorView.currentPanel().handleCopyEvent(event); WebInspector.documentCopyEventFired(event); } WebInspector.documentCopyEventFired = function(event) { } WebInspector.contextMenuEventFired = function(event) { if (event.handled || event.target.hasStyleClass("popup-glasspane")) event.preventDefault(); } WebInspector.showConsole = function() { if (WebInspector._toggleConsoleButton && !WebInspector._toggleConsoleButton.toggled) { if (WebInspector.drawer.visible) this._closePreviousDrawerView(); WebInspector._toggleConsoleButtonClicked(); } } WebInspector.showPanel = function(panel) { return WebInspector.inspectorView.showPanel(panel); } WebInspector.panel = function(panel) { return WebInspector.inspectorView.panel(panel); } WebInspector.bringToFront = function() { InspectorFrontendHost.bringToFront(); } WebInspector.log = function(message, messageLevel, showConsole) { var self = this; function isLogAvailable() { return WebInspector.ConsoleMessage && WebInspector.RemoteObject && self.console; } function flushQueue() { var queued = WebInspector.log.queued; if (!queued) return; for (var i = 0; i < queued.length; ++i) logMessage(queued[i]); delete WebInspector.log.queued; } function flushQueueIfAvailable() { if (!isLogAvailable()) return; clearInterval(WebInspector.log.interval); delete WebInspector.log.interval; flushQueue(); } function logMessage(message) { var msg = WebInspector.ConsoleMessage.create( WebInspector.ConsoleMessage.MessageSource.Other, messageLevel || WebInspector.ConsoleMessage.MessageLevel.Debug, message); self.console.addMessage(msg); if (showConsole) WebInspector.showConsole(); } if (!isLogAvailable()) { if (!WebInspector.log.queued) WebInspector.log.queued = []; WebInspector.log.queued.push(message); if (!WebInspector.log.interval) WebInspector.log.interval = setInterval(flushQueueIfAvailable, 1000); return; } flushQueue(); logMessage(message); } WebInspector.showErrorMessage = function(error) { WebInspector.log(error, WebInspector.ConsoleMessage.MessageLevel.Error, true); } WebInspector.inspect = function(payload, hints) { var object = WebInspector.RemoteObject.fromPayload(payload); if (object.subtype === "node") { function callback(nodeId) { WebInspector._updateFocusedNode(nodeId); object.release(); } object.pushNodeToFrontend(callback); return; } if (hints.databaseId) WebInspector.showPanel("resources").selectDatabase(WebInspector.databaseModel.databaseForId(hints.databaseId)); else if (hints.domStorageId) WebInspector.showPanel("resources").selectDOMStorage(WebInspector.domStorageModel.storageForId(hints.domStorageId)); object.release(); } WebInspector.detached = function(reason) { WebInspector.socket._detachReason = reason; (new WebInspector.RemoteDebuggingTerminatedScreen(reason)).showModal(); } WebInspector._updateFocusedNode = function(nodeId) { if (WebInspector._nodeSearchButton.toggled) { InspectorFrontendHost.bringToFront(); WebInspector._nodeSearchButton.toggled = false; } WebInspector.showPanel("elements").revealAndSelectNode(nodeId); } WebInspector._showAnchorLocation = function(anchor) { if (WebInspector.openAnchorLocationRegistry.dispatch({ url: anchor.href, lineNumber: anchor.lineNumber})) return true; var preferredPanel = this.panels[anchor.preferredPanel]; if (preferredPanel && WebInspector._showAnchorLocationInPanel(anchor, preferredPanel)) return true; if (WebInspector._showAnchorLocationInPanel(anchor, this.panel("scripts"))) return true; if (WebInspector._showAnchorLocationInPanel(anchor, this.panel("resources"))) return true; if (WebInspector._showAnchorLocationInPanel(anchor, this.panel("network"))) return true; return false; } WebInspector._showAnchorLocationInPanel = function(anchor, panel) { if (!panel || !panel.canShowAnchorLocation(anchor)) return false; if (anchor.hasStyleClass("webkit-html-external-link")) { anchor.removeStyleClass("webkit-html-external-link"); anchor.addStyleClass("webkit-html-resource-link"); } WebInspector.inspectorView.showPanelForAnchorNavigation(panel); panel.showAnchorLocation(anchor); return true; } WebInspector.showProfileForURL = function(url) { WebInspector.showPanel("profiles").showProfileForURL(url); } WebInspector.evaluateInConsole = function(expression, showResultOnly) { this.showConsole(); this.consoleView.evaluateUsingTextPrompt(expression, showResultOnly); } WebInspector.addMainEventListeners = function(doc) { doc.addEventListener("keydown", this.documentKeyDown.bind(this), true); doc.addEventListener("keydown", this.postDocumentKeyDown.bind(this), false); doc.addEventListener("beforecopy", this.documentCanCopy.bind(this), true); doc.addEventListener("copy", this.documentCopy.bind(this), true); doc.addEventListener("contextmenu", this.contextMenuEventFired.bind(this), true); doc.addEventListener("click", this.documentClick.bind(this), true); } WebInspector.ProfileURLRegExp = /webkit-profile:\/\/(.+)\/(.+)#([0-9]+)/; WebInspector.Zoom = { Table: [0.25, 0.33, 0.5, 0.66, 0.75, 0.9, 1, 1.1, 1.25, 1.5, 1.75, 2, 2.5, 3, 4, 5], DefaultOffset: 6 } WebInspector.UIString = function(string, vararg) { if (Preferences.localizeUI) { if (window.localizedStrings && string in window.localizedStrings) string = window.localizedStrings[string]; else { if (!(string in WebInspector._missingLocalizedStrings)) { console.warn("Localized string \"" + string + "\" not found."); WebInspector._missingLocalizedStrings[string] = true; } if (Preferences.showMissingLocalizedStrings) string += " (not localized)"; } } return String.vsprintf(string, Array.prototype.slice.call(arguments, 1)); } WebInspector._missingLocalizedStrings = {}; WebInspector.installDragHandle = function(element, elementDragStart, elementDrag, elementDragEnd, cursor) { element.addEventListener("mousedown", WebInspector._elementDragStart.bind(WebInspector, elementDragStart, elementDrag, elementDragEnd, cursor), false); } WebInspector._elementDragStart = function(elementDragStart, elementDrag, elementDragEnd, cursor, event) { if (event.button || (WebInspector.isMac() && event.ctrlKey)) return; if (WebInspector._elementDraggingEventListener) return; if (elementDragStart && !elementDragStart(event)) return; if (WebInspector._elementDraggingGlassPane) { WebInspector._elementDraggingGlassPane.dispose(); delete WebInspector._elementDraggingGlassPane; } var targetDocument = event.target.ownerDocument; WebInspector._elementDraggingEventListener = elementDrag; WebInspector._elementEndDraggingEventListener = elementDragEnd; WebInspector._mouseOutWhileDraggingTargetDocument = targetDocument; targetDocument.addEventListener("mousemove", WebInspector._elementDraggingEventListener, true); targetDocument.addEventListener("mouseup", WebInspector._elementDragEnd, true); targetDocument.addEventListener("mouseout", WebInspector._mouseOutWhileDragging, true); targetDocument.body.style.cursor = cursor; event.preventDefault(); } WebInspector._mouseOutWhileDragging = function() { WebInspector._unregisterMouseOutWhileDragging(); WebInspector._elementDraggingGlassPane = new WebInspector.GlassPane(); } WebInspector._unregisterMouseOutWhileDragging = function() { if (!WebInspector._mouseOutWhileDraggingTargetDocument) return; WebInspector._mouseOutWhileDraggingTargetDocument.removeEventListener("mouseout", WebInspector._mouseOutWhileDragging, true); delete WebInspector._mouseOutWhileDraggingTargetDocument; } WebInspector._elementDragEnd = function(event) { var targetDocument = event.target.ownerDocument; targetDocument.removeEventListener("mousemove", WebInspector._elementDraggingEventListener, true); targetDocument.removeEventListener("mouseup", WebInspector._elementDragEnd, true); WebInspector._unregisterMouseOutWhileDragging(); targetDocument.body.style.removeProperty("cursor"); if (WebInspector._elementDraggingGlassPane) WebInspector._elementDraggingGlassPane.dispose(); var elementDragEnd = WebInspector._elementEndDraggingEventListener; delete WebInspector._elementDraggingGlassPane; delete WebInspector._elementDraggingEventListener; delete WebInspector._elementEndDraggingEventListener; event.preventDefault(); if (elementDragEnd) elementDragEnd(event); } WebInspector.GlassPane = function() { this.element = document.createElement("div"); this.element.style.cssText = "position:absolute;top:0;bottom:0;left:0;right:0;background-color:transparent;z-index:1000;"; this.element.id = "glass-pane-for-drag"; document.body.appendChild(this.element); } WebInspector.GlassPane.prototype = { dispose: function() { if (this.element.parentElement) this.element.parentElement.removeChild(this.element); } } WebInspector.animateStyle = function(animations, duration, callback) { var interval; var complete = 0; var hasCompleted = false; const intervalDuration = (1000 / 30); const animationsLength = animations.length; const propertyUnit = {opacity: ""}; const defaultUnit = "px"; function cubicInOut(t, b, c, d) { if ((t/=d/2) < 1) return c/2*t*t*t + b; return c/2*((t-=2)*t*t + 2) + b; } for (var i = 0; i < animationsLength; ++i) { var animation = animations[i]; var element = null, start = null, end = null, key = null; for (key in animation) { if (key === "element") element = animation[key]; else if (key === "start") start = animation[key]; else if (key === "end") end = animation[key]; } if (!element || !end) continue; if (!start) { var computedStyle = element.ownerDocument.defaultView.getComputedStyle(element); start = {}; for (key in end) start[key] = parseInt(computedStyle.getPropertyValue(key), 10); animation.start = start; } else for (key in start) element.style.setProperty(key, start[key] + (key in propertyUnit ? propertyUnit[key] : defaultUnit)); } function animateLoop() { if (hasCompleted) return; complete += intervalDuration; var next = complete + intervalDuration; for (var i = 0; i < animationsLength; ++i) { var animation = animations[i]; var element = animation.element; var start = animation.start; var end = animation.end; if (!element || !end) continue; var style = element.style; for (key in end) { var endValue = end[key]; if (next < duration) { var startValue = start[key]; var newValue = cubicInOut(complete, startValue, endValue - startValue, duration); style.setProperty(key, newValue + (key in propertyUnit ? propertyUnit[key] : defaultUnit)); } else style.setProperty(key, endValue + (key in propertyUnit ? propertyUnit[key] : defaultUnit)); } } if (complete >= duration) { hasCompleted = true; clearInterval(interval); if (callback) callback(); } } function forceComplete() { if (hasCompleted) return; complete = duration; animateLoop(); } function cancel() { hasCompleted = true; clearInterval(interval); } interval = setInterval(animateLoop, intervalDuration); return { cancel: cancel, forceComplete: forceComplete }; } WebInspector.isBeingEdited = function(element) { if (element.hasStyleClass("text-prompt") || element.nodeName === "INPUT") return true; if (!WebInspector.__editingCount) return false; while (element) { if (element.__editing) return true; element = element.parentElement; } return false; } WebInspector.markBeingEdited = function(element, value) { if (value) { if (element.__editing) return false; element.__editing = true; WebInspector.__editingCount = (WebInspector.__editingCount || 0) + 1; } else { if (!element.__editing) return false; delete element.__editing; --WebInspector.__editingCount; } return true; } WebInspector.EditingConfig = function(commitHandler, cancelHandler, context) { this.commitHandler = commitHandler; this.cancelHandler = cancelHandler this.context = context; this.pasteHandler; this.multiline; this.customFinishHandler; } WebInspector.EditingConfig.prototype = { setPasteHandler: function(pasteHandler) { this.pasteHandler = pasteHandler; }, setMultiline: function(multiline) { this.multiline = multiline; }, setCustomFinishHandler: function(customFinishHandler) { this.customFinishHandler = customFinishHandler; } } WebInspector.CSSNumberRegex = /^(-?(?:\d+(?:\.\d+)?|\.\d+))$/; WebInspector.StyleValueDelimiters = " \xA0\t\n\"':;,/()"; WebInspector._valueModificationDirection = function(event) { var direction = null; if (event.type === "mousewheel") { if (event.wheelDeltaY > 0) direction = "Up"; else if (event.wheelDeltaY < 0) direction = "Down"; } else { if (event.keyIdentifier === "Up" || event.keyIdentifier === "PageUp") direction = "Up"; else if (event.keyIdentifier === "Down" || event.keyIdentifier === "PageDown") direction = "Down"; } return direction; } WebInspector._modifiedHexValue = function(hexString, event) { var direction = WebInspector._valueModificationDirection(event); if (!direction) return hexString; var number = parseInt(hexString, 16); if (isNaN(number) || !isFinite(number)) return hexString; var maxValue = Math.pow(16, hexString.length) - 1; var arrowKeyOrMouseWheelEvent = (event.keyIdentifier === "Up" || event.keyIdentifier === "Down" || event.type === "mousewheel"); var delta; if (arrowKeyOrMouseWheelEvent) delta = (direction === "Up") ? 1 : -1; else delta = (event.keyIdentifier === "PageUp") ? 16 : -16; if (event.shiftKey) delta *= 16; var result = number + delta; if (result < 0) result = 0; else if (result > maxValue) return hexString; var resultString = result.toString(16).toUpperCase(); for (var i = 0, lengthDelta = hexString.length - resultString.length; i < lengthDelta; ++i) resultString = "0" + resultString; return resultString; } WebInspector._modifiedFloatNumber = function(number, event) { var direction = WebInspector._valueModificationDirection(event); if (!direction) return number; var arrowKeyOrMouseWheelEvent = (event.keyIdentifier === "Up" || event.keyIdentifier === "Down" || event.type === "mousewheel"); var changeAmount = 1; if (event.shiftKey && !arrowKeyOrMouseWheelEvent) changeAmount = 100; else if (event.shiftKey || !arrowKeyOrMouseWheelEvent) changeAmount = 10; else if (event.altKey) changeAmount = 0.1; if (direction === "Down") changeAmount *= -1; var result = Number((number + changeAmount).toFixed(6)); if (!String(result).match(WebInspector.CSSNumberRegex)) return null; return result; } WebInspector.handleElementValueModifications = function(event, element, finishHandler, suggestionHandler, customNumberHandler) { var arrowKeyOrMouseWheelEvent = (event.keyIdentifier === "Up" || event.keyIdentifier === "Down" || event.type === "mousewheel"); var pageKeyPressed = (event.keyIdentifier === "PageUp" || event.keyIdentifier === "PageDown"); if (!arrowKeyOrMouseWheelEvent && !pageKeyPressed) return false; var selection = window.getSelection(); if (!selection.rangeCount) return false; var selectionRange = selection.getRangeAt(0); if (!selectionRange.commonAncestorContainer.isSelfOrDescendant(element)) return false; var originalValue = element.textContent; var wordRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, WebInspector.StyleValueDelimiters, element); var wordString = wordRange.toString(); if (suggestionHandler && suggestionHandler(wordString)) return false; var replacementString; var prefix, suffix, number; var matches; matches = /(.*#)([\da-fA-F]+)(.*)/.exec(wordString); if (matches && matches.length) { prefix = matches[1]; suffix = matches[3]; number = WebInspector._modifiedHexValue(matches[2], event); if (customNumberHandler) number = customNumberHandler(number); replacementString = prefix + number + suffix; } else { matches = /(.*?)(-?(?:\d+(?:\.\d+)?|\.\d+))(.*)/.exec(wordString); if (matches && matches.length) { prefix = matches[1]; suffix = matches[3]; number = WebInspector._modifiedFloatNumber(parseFloat(matches[2]), event); if (number === null) return false; if (customNumberHandler) number = customNumberHandler(number); replacementString = prefix + number + suffix; } } if (replacementString) { var replacementTextNode = document.createTextNode(replacementString); wordRange.deleteContents(); wordRange.insertNode(replacementTextNode); var finalSelectionRange = document.createRange(); finalSelectionRange.setStart(replacementTextNode, 0); finalSelectionRange.setEnd(replacementTextNode, replacementString.length); selection.removeAllRanges(); selection.addRange(finalSelectionRange); event.handled = true; event.preventDefault(); if (finishHandler) finishHandler(originalValue, replacementString); return true; } return false; } WebInspector.startEditing = function(element, config) { if (!WebInspector.markBeingEdited(element, true)) return null; config = config || new WebInspector.EditingConfig(function() {}, function() {}); var committedCallback = config.commitHandler; var cancelledCallback = config.cancelHandler; var pasteCallback = config.pasteHandler; var context = config.context; var oldText = getContent(element); var moveDirection = ""; element.addStyleClass("editing"); var oldTabIndex = element.getAttribute("tabIndex"); if (typeof oldTabIndex !== "number" || oldTabIndex < 0) element.tabIndex = 0; function blurEventListener() { editingCommitted.call(element); } function getContent(element) { if (element.tagName === "INPUT" && element.type === "text") return element.value; else return element.textContent; } function cleanUpAfterEditing() { WebInspector.markBeingEdited(element, false); this.removeStyleClass("editing"); if (typeof oldTabIndex !== "number") element.removeAttribute("tabIndex"); else this.tabIndex = oldTabIndex; this.scrollTop = 0; this.scrollLeft = 0; element.removeEventListener("blur", blurEventListener, false); element.removeEventListener("keydown", keyDownEventListener, true); if (pasteCallback) element.removeEventListener("paste", pasteEventListener, true); WebInspector.restoreFocusFromElement(element); } function editingCancelled() { if (this.tagName === "INPUT" && this.type === "text") this.value = oldText; else this.textContent = oldText; cleanUpAfterEditing.call(this); cancelledCallback(this, context); } function editingCommitted() { cleanUpAfterEditing.call(this); committedCallback(this, getContent(this), oldText, context, moveDirection); } function defaultFinishHandler(event) { var isMetaOrCtrl = WebInspector.isMac() ? event.metaKey && !event.shiftKey && !event.ctrlKey && !event.altKey : event.ctrlKey && !event.shiftKey && !event.metaKey && !event.altKey; if (isEnterKey(event) && (event.isMetaOrCtrlForTest || !config.multiline || isMetaOrCtrl)) return "commit"; else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code || event.keyIdentifier === "U+001B") return "cancel"; else if (event.keyIdentifier === "U+0009") return "move-" + (event.shiftKey ? "backward" : "forward"); } function handleEditingResult(result, event) { if (result === "commit") { editingCommitted.call(element); event.consume(true); } else if (result === "cancel") { editingCancelled.call(element); event.consume(true); } else if (result && result.startsWith("move-")) { moveDirection = result.substring(5); if (event.keyIdentifier !== "U+0009") blurEventListener(); } } function pasteEventListener(event) { var result = pasteCallback(event); handleEditingResult(result, event); } function keyDownEventListener(event) { var handler = config.customFinishHandler || defaultFinishHandler; var result = handler(event); handleEditingResult(result, event); } element.addEventListener("blur", blurEventListener, false); element.addEventListener("keydown", keyDownEventListener, true); if (pasteCallback) element.addEventListener("paste", pasteEventListener, true); WebInspector.setCurrentFocusElement(element); return { cancel: editingCancelled.bind(element), commit: editingCommitted.bind(element) }; } Number.secondsToString = function(seconds, higherResolution) { if (seconds === 0) return "0"; var ms = seconds * 1000; if (higherResolution && ms < 1000) return WebInspector.UIString("%.3fms", ms); else if (ms < 1000) return WebInspector.UIString("%.0fms", ms); if (seconds < 60) return WebInspector.UIString("%.2fs", seconds); var minutes = seconds / 60; if (minutes < 60) return WebInspector.UIString("%.1fmin", minutes); var hours = minutes / 60; if (hours < 24) return WebInspector.UIString("%.1fhrs", hours); var days = hours / 24; return WebInspector.UIString("%.1f days", days); } Number.bytesToString = function(bytes, higherResolution) { if (typeof higherResolution === "undefined") higherResolution = true; if (bytes < 1024) return WebInspector.UIString("%.0fB", bytes); var kilobytes = bytes / 1024; if (higherResolution && kilobytes < 1024) return WebInspector.UIString("%.2fKB", kilobytes); else if (kilobytes < 1024) return WebInspector.UIString("%.0fKB", kilobytes); var megabytes = kilobytes / 1024; if (higherResolution) return WebInspector.UIString("%.2fMB", megabytes); else return WebInspector.UIString("%.0fMB", megabytes); } Number.withThousandsSeparator = function(num) { var str = num + ""; var re = /(\d+)(\d{3})/; while (str.match(re)) str = str.replace(re, "$1\u2009$2"); return str; } WebInspector.useLowerCaseMenuTitles = function() { return WebInspector.platform() === "windows" && Preferences.useLowerCaseMenuTitlesOnWindows; } WebInspector.formatLocalized = function(format, substitutions, formatters, initialValue, append) { return String.format(WebInspector.UIString(format), substitutions, formatters, initialValue, append); } WebInspector.openLinkExternallyLabel = function() { return WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Open link in new tab" : "Open Link in New Tab"); } WebInspector.copyLinkAddressLabel = function() { return WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Copy link address" : "Copy Link Address"); } WebInspector.platform = function() { if (!WebInspector._platform) WebInspector._platform = InspectorFrontendHost.platform(); return WebInspector._platform; } WebInspector.isMac = function() { if (typeof WebInspector._isMac === "undefined") WebInspector._isMac = WebInspector.platform() === "mac"; return WebInspector._isMac; } WebInspector.isWin = function() { if (typeof WebInspector._isWin === "undefined") WebInspector._isWin = WebInspector.platform() === "windows"; return WebInspector._isWin; } WebInspector.PlatformFlavor = { WindowsVista: "windows-vista", MacTiger: "mac-tiger", MacLeopard: "mac-leopard", MacSnowLeopard: "mac-snowleopard" } WebInspector.platformFlavor = function() { function detectFlavor() { const userAgent = navigator.userAgent; if (WebInspector.platform() === "windows") { var match = userAgent.match(/Windows NT (\d+)\.(?:\d+)/); if (match && match[1] >= 6) return WebInspector.PlatformFlavor.WindowsVista; return null; } else if (WebInspector.platform() === "mac") { var match = userAgent.match(/Mac OS X\s*(?:(\d+)_(\d+))?/); if (!match || match[1] != 10) return WebInspector.PlatformFlavor.MacSnowLeopard; switch (Number(match[2])) { case 4: return WebInspector.PlatformFlavor.MacTiger; case 5: return WebInspector.PlatformFlavor.MacLeopard; case 6: default: return WebInspector.PlatformFlavor.MacSnowLeopard; } } } if (!WebInspector._platformFlavor) WebInspector._platformFlavor = detectFlavor(); return WebInspector._platformFlavor; } WebInspector.port = function() { if (!WebInspector._port) WebInspector._port = InspectorFrontendHost.port(); return WebInspector._port; } WebInspector.installPortStyles = function() { var platform = WebInspector.platform(); document.body.addStyleClass("platform-" + platform); var flavor = WebInspector.platformFlavor(); if (flavor) document.body.addStyleClass("platform-" + flavor); var port = WebInspector.port(); document.body.addStyleClass("port-" + port); } WebInspector._windowFocused = function(event) { if (event.target.document.nodeType === Node.DOCUMENT_NODE) document.body.removeStyleClass("inactive"); } WebInspector._windowBlurred = function(event) { if (event.target.document.nodeType === Node.DOCUMENT_NODE) document.body.addStyleClass("inactive"); } WebInspector.previousFocusElement = function() { return WebInspector._previousFocusElement; } WebInspector.currentFocusElement = function() { return WebInspector._currentFocusElement; } WebInspector._focusChanged = function(event) { WebInspector.setCurrentFocusElement(event.target); } WebInspector._textInputTypes = ["text", "search", "tel", "url", "email", "password"].keySet(); WebInspector._isTextEditingElement = function(element) { if (element instanceof HTMLInputElement) return element.type in WebInspector._textInputTypes; if (element instanceof HTMLTextAreaElement) return true; return false; } WebInspector.setCurrentFocusElement = function(x) { if (WebInspector._currentFocusElement !== x) WebInspector._previousFocusElement = WebInspector._currentFocusElement; WebInspector._currentFocusElement = x; if (WebInspector._currentFocusElement) { WebInspector._currentFocusElement.focus(); var selection = window.getSelection(); if (!WebInspector._isTextEditingElement(WebInspector._currentFocusElement) && selection.isCollapsed && !WebInspector._currentFocusElement.isInsertionCaretInside()) { var selectionRange = WebInspector._currentFocusElement.ownerDocument.createRange(); selectionRange.setStart(WebInspector._currentFocusElement, 0); selectionRange.setEnd(WebInspector._currentFocusElement, 0); selection.removeAllRanges(); selection.addRange(selectionRange); } } else if (WebInspector._previousFocusElement) WebInspector._previousFocusElement.blur(); } WebInspector.restoreFocusFromElement = function(element) { if (element && element.isSelfOrAncestor(WebInspector.currentFocusElement())) WebInspector.setCurrentFocusElement(WebInspector.previousFocusElement()); } WebInspector.setToolbarColors = function(backgroundColor, color) { if (!WebInspector._themeStyleElement) { WebInspector._themeStyleElement = document.createElement("style"); document.head.appendChild(WebInspector._themeStyleElement); } WebInspector._themeStyleElement.textContent = "#toolbar {\ background-image: none !important;\ background-color: " + backgroundColor + " !important;\ }\ \ .toolbar-label {\ color: " + color + " !important;\ text-shadow: none;\ }"; } WebInspector.resetToolbarColors = function() { if (WebInspector._themeStyleElement) WebInspector._themeStyleElement.textContent = ""; } WebInspector.highlightSearchResult = function(element, offset, length, domChanges) { var result = WebInspector.highlightSearchResults(element, [{offset: offset, length: length }], domChanges); return result.length ? result[0] : null; } WebInspector.highlightSearchResults = function(element, resultRanges, changes) { return WebInspector.highlightRangesWithStyleClass(element, resultRanges, "webkit-search-result", changes); } WebInspector.highlightRangesWithStyleClass = function(element, resultRanges, styleClass, changes) { changes = changes || []; var highlightNodes = []; var lineText = element.textContent; var ownerDocument = element.ownerDocument; var textNodeSnapshot = ownerDocument.evaluate(".//text()", element, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); var snapshotLength = textNodeSnapshot.snapshotLength; if (snapshotLength === 0) return highlightNodes; var nodeRanges = []; var rangeEndOffset = 0; for (var i = 0; i < snapshotLength; ++i) { var range = {}; range.offset = rangeEndOffset; range.length = textNodeSnapshot.snapshotItem(i).textContent.length; rangeEndOffset = range.offset + range.length; nodeRanges.push(range); } var startIndex = 0; for (var i = 0; i < resultRanges.length; ++i) { var startOffset = resultRanges[i].offset; var endOffset = startOffset + resultRanges[i].length; while (startIndex < snapshotLength && nodeRanges[startIndex].offset + nodeRanges[startIndex].length <= startOffset) startIndex++; var endIndex = startIndex; while (endIndex < snapshotLength && nodeRanges[endIndex].offset + nodeRanges[endIndex].length < endOffset) endIndex++; if (endIndex === snapshotLength) break; var highlightNode = ownerDocument.createElement("span"); highlightNode.className = styleClass; highlightNode.textContent = lineText.substring(startOffset, endOffset); var lastTextNode = textNodeSnapshot.snapshotItem(endIndex); var lastText = lastTextNode.textContent; lastTextNode.textContent = lastText.substring(endOffset - nodeRanges[endIndex].offset); changes.push({ node: lastTextNode, type: "changed", oldText: lastText, newText: lastTextNode.textContent }); if (startIndex === endIndex) { lastTextNode.parentElement.insertBefore(highlightNode, lastTextNode); changes.push({ node: highlightNode, type: "added", nextSibling: lastTextNode, parent: lastTextNode.parentElement }); highlightNodes.push(highlightNode); var prefixNode = ownerDocument.createTextNode(lastText.substring(0, startOffset - nodeRanges[startIndex].offset)); lastTextNode.parentElement.insertBefore(prefixNode, highlightNode); changes.push({ node: prefixNode, type: "added", nextSibling: highlightNode, parent: lastTextNode.parentElement }); } else { var firstTextNode = textNodeSnapshot.snapshotItem(startIndex); var firstText = firstTextNode.textContent; var anchorElement = firstTextNode.nextSibling; firstTextNode.parentElement.insertBefore(highlightNode, anchorElement); changes.push({ node: highlightNode, type: "added", nextSibling: anchorElement, parent: firstTextNode.parentElement }); highlightNodes.push(highlightNode); firstTextNode.textContent = firstText.substring(0, startOffset - nodeRanges[startIndex].offset); changes.push({ node: firstTextNode, type: "changed", oldText: firstText, newText: firstTextNode.textContent }); for (var j = startIndex + 1; j < endIndex; j++) { var textNode = textNodeSnapshot.snapshotItem(j); var text = textNode.textContent; textNode.textContent = ""; changes.push({ node: textNode, type: "changed", oldText: text, newText: textNode.textContent }); } } startIndex = endIndex; nodeRanges[startIndex].offset = endOffset; nodeRanges[startIndex].length = lastTextNode.textContent.length; } return highlightNodes; } WebInspector.applyDomChanges = function(domChanges) { for (var i = 0, size = domChanges.length; i < size; ++i) { var entry = domChanges[i]; switch (entry.type) { case "added": entry.parent.insertBefore(entry.node, entry.nextSibling); break; case "changed": entry.node.textContent = entry.newText; break; } } } WebInspector.revertDomChanges = function(domChanges) { for (var i = domChanges.length - 1; i >= 0; --i) { var entry = domChanges[i]; switch (entry.type) { case "added": if (entry.node.parentElement) entry.node.parentElement.removeChild(entry.node); break; case "changed": entry.node.textContent = entry.oldText; break; } } } WebInspector._coalescingLevel = 0; WebInspector.startBatchUpdate = function() { if (!WebInspector._coalescingLevel) WebInspector._postUpdateHandlers = new Map(); WebInspector._coalescingLevel++; } WebInspector.endBatchUpdate = function() { if (--WebInspector._coalescingLevel) return; var handlers = WebInspector._postUpdateHandlers; delete WebInspector._postUpdateHandlers; var keys = handlers.keys(); for (var i = 0; i < keys.length; ++i) { var object = keys[i]; var methods = handlers.get(object).keys(); for (var j = 0; j < methods.length; ++j) methods[j].call(object); } } WebInspector.invokeOnceAfterBatchUpdate = function(object, method) { if (!WebInspector._coalescingLevel) { method.call(object); return; } var methods = WebInspector._postUpdateHandlers.get(object); if (!methods) { methods = new Map(); WebInspector._postUpdateHandlers.put(object, methods); } methods.put(method); } ;(function() { function windowLoaded() { window.addEventListener("focus", WebInspector._windowFocused, false); window.addEventListener("blur", WebInspector._windowBlurred, false); document.addEventListener("focus", WebInspector._focusChanged.bind(this), true); window.removeEventListener("DOMContentLoaded", windowLoaded, false); } window.addEventListener("DOMContentLoaded", windowLoaded, false); })(); function InspectorBackendClass() { this._lastCallbackId = 1; this._pendingResponsesCount = 0; this._callbacks = {}; this._domainDispatchers = {}; this._eventArgs = {}; this._replyArgs = {}; this.dumpInspectorTimeStats = false; this.dumpInspectorProtocolMessages = false; this._initialized = false; } InspectorBackendClass.prototype = { _wrap: function(callback, method) { var callbackId = this._lastCallbackId++; if (!callback) callback = function() {}; this._callbacks[callbackId] = callback; callback.methodName = method; if (this.dumpInspectorTimeStats) callback.sendRequestTime = Date.now(); return callbackId; }, registerCommand: function(method, signature, replyArgs) { var domainAndMethod = method.split("."); var agentName = domainAndMethod[0] + "Agent"; if (!window[agentName]) window[agentName] = {}; window[agentName][domainAndMethod[1]] = this._sendMessageToBackend.bind(this, method, signature); window[agentName][domainAndMethod[1]]["invoke"] = this._invoke.bind(this, method, signature); this._replyArgs[method] = replyArgs; this._initialized = true; }, registerEvent: function(eventName, params) { this._eventArgs[eventName] = params; this._initialized = true; }, _invoke: function(method, signature, args, callback) { this._wrapCallbackAndSendMessageObject(method, args, callback); }, _sendMessageToBackend: function(method, signature, vararg) { var args = Array.prototype.slice.call(arguments, 2); var callback = (args.length && typeof args[args.length - 1] === "function") ? args.pop() : null; var params = {}; var hasParams = false; for (var i = 0; i < signature.length; ++i) { var param = signature[i]; var paramName = param["name"]; var typeName = param["type"]; var optionalFlag = param["optional"]; if (!args.length && !optionalFlag) { console.error("Protocol Error: Invalid number of arguments for method '" + method + "' call. It must have the following arguments '" + JSON.stringify(signature) + "'."); return; } var value = args.shift(); if (optionalFlag && typeof value === "undefined") { continue; } if (typeof value !== typeName) { console.error("Protocol Error: Invalid type of argument '" + paramName + "' for method '" + method + "' call. It must be '" + typeName + "' but it is '" + typeof value + "'."); return; } params[paramName] = value; hasParams = true; } if (args.length === 1 && !callback) { if (typeof args[0] !== "undefined") { console.error("Protocol Error: Optional callback argument for method '" + method + "' call must be a function but its type is '" + typeof args[0] + "'."); return; } } this._wrapCallbackAndSendMessageObject(method, hasParams ? params : null, callback); }, _wrapCallbackAndSendMessageObject: function(method, params, callback) { var messageObject = {}; messageObject.method = method; if (params) messageObject.params = params; messageObject.id = this._wrap(callback, method); if (this.dumpInspectorProtocolMessages) console.log("frontend: " + JSON.stringify(messageObject)); ++this._pendingResponsesCount; this.sendMessageObjectToBackend(messageObject); }, sendMessageObjectToBackend: function(messageObject) { var message = JSON.stringify(messageObject); InspectorFrontendHost.sendMessageToBackend(message); }, registerDomainDispatcher: function(domain, dispatcher) { this._domainDispatchers[domain] = dispatcher; }, dispatch: function(message) { if (this.dumpInspectorProtocolMessages) console.log("backend: " + ((typeof message === "string") ? message : JSON.stringify(message))); var messageObject = (typeof message === "string") ? JSON.parse(message) : message; if ("id" in messageObject) { if (messageObject.error) { if (messageObject.error.code !== -32000) this.reportProtocolError(messageObject); } var callback = this._callbacks[messageObject.id]; if (callback) { var argumentsArray = []; if (messageObject.result) { var paramNames = this._replyArgs[callback.methodName]; if (paramNames) { for (var i = 0; i < paramNames.length; ++i) argumentsArray.push(messageObject.result[paramNames[i]]); } } var processingStartTime; if (this.dumpInspectorTimeStats && callback.methodName) processingStartTime = Date.now(); argumentsArray.unshift(messageObject.error ? messageObject.error.message : null); callback.apply(null, argumentsArray); --this._pendingResponsesCount; delete this._callbacks[messageObject.id]; if (this.dumpInspectorTimeStats && callback.methodName) console.log("time-stats: " + callback.methodName + " = " + (processingStartTime - callback.sendRequestTime) + " + " + (Date.now() - processingStartTime)); } if (this._scripts && !this._pendingResponsesCount) this.runAfterPendingDispatches(); return; } else { var method = messageObject.method.split("."); var domainName = method[0]; var functionName = method[1]; if (!(domainName in this._domainDispatchers)) { console.error("Protocol Error: the message is for non-existing domain '" + domainName + "'"); return; } var dispatcher = this._domainDispatchers[domainName]; if (!(functionName in dispatcher)) { console.error("Protocol Error: Attempted to dispatch an unimplemented method '" + messageObject.method + "'"); return; } if (!this._eventArgs[messageObject.method]) { console.error("Protocol Error: Attempted to dispatch an unspecified method '" + messageObject.method + "'"); return; } var params = []; if (messageObject.params) { var paramNames = this._eventArgs[messageObject.method]; for (var i = 0; i < paramNames.length; ++i) params.push(messageObject.params[paramNames[i]]); } var processingStartTime; if (this.dumpInspectorTimeStats) processingStartTime = Date.now(); dispatcher[functionName].apply(dispatcher, params); if (this.dumpInspectorTimeStats) console.log("time-stats: " + messageObject.method + " = " + (Date.now() - processingStartTime)); } }, reportProtocolError: function(messageObject) { console.error("Request with id = " + messageObject.id + " failed. " + messageObject.error); }, runAfterPendingDispatches: function(script) { if (!this._scripts) this._scripts = []; if (script) this._scripts.push(script); if (!this._pendingResponsesCount) { var scripts = this._scripts; this._scripts = [] for (var id = 0; id < scripts.length; ++id) scripts[id].call(this); } }, loadFromJSONIfNeeded: function(jsonUrl) { if (this._initialized) return; var xhr = new XMLHttpRequest(); xhr.open("GET", jsonUrl, false); xhr.send(null); var schema = JSON.parse(xhr.responseText); var jsTypes = { integer: "number", array: "object" }; var rawTypes = {}; var domains = schema["domains"]; for (var i = 0; i < domains.length; ++i) { var domain = domains[i]; for (var j = 0; domain.types && j < domain.types.length; ++j) { var type = domain.types[j]; rawTypes[domain.domain + "." + type.id] = jsTypes[type.type] || type.type; } } var result = []; for (var i = 0; i < domains.length; ++i) { var domain = domains[i]; var commands = domain["commands"] || []; for (var j = 0; j < commands.length; ++j) { var command = commands[j]; var parameters = command["parameters"]; var paramsText = []; for (var k = 0; parameters && k < parameters.length; ++k) { var parameter = parameters[k]; var type; if (parameter.type) type = jsTypes[parameter.type] || parameter.type; else { var ref = parameter["$ref"]; if (ref.indexOf(".") !== -1) type = rawTypes[ref]; else type = rawTypes[domain.domain + "." + ref]; } var text = "{\"name\": \"" + parameter.name + "\", \"type\": \"" + type + "\", \"optional\": " + (parameter.optional ? "true" : "false") + "}"; paramsText.push(text); } var returnsText = []; var returns = command["returns"] || []; for (var k = 0; k < returns.length; ++k) { var parameter = returns[k]; returnsText.push("\"" + parameter.name + "\""); } result.push("InspectorBackend.registerCommand(\"" + domain.domain + "." + command.name + "\", [" + paramsText.join(", ") + "], [" + returnsText.join(", ") + "]);"); } for (var j = 0; domain.events && j < domain.events.length; ++j) { var event = domain.events[j]; var paramsText = []; for (var k = 0; event.parameters && k < event.parameters.length; ++k) { var parameter = event.parameters[k]; paramsText.push("\"" + parameter.name + "\""); } result.push("InspectorBackend.registerEvent(\"" + domain.domain + "." + event.name + "\", [" + paramsText.join(", ") + "]);"); } result.push("InspectorBackend.register" + domain.domain + "Dispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, \"" + domain.domain + "\");"); } eval(result.join("\n")); } } InspectorBackend = new InspectorBackendClass(); InspectorBackend.registerInspectorDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Inspector"); InspectorBackend.registerEvent("Inspector.evaluateForTestInFrontend", ["testCallId", "script"]); InspectorBackend.registerEvent("Inspector.inspect", ["object", "hints"]); InspectorBackend.registerEvent("Inspector.detached", ["reason"]); InspectorBackend.registerCommand("Inspector.enable", [], []); InspectorBackend.registerCommand("Inspector.disable", [], []); InspectorBackend.registerMemoryDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Memory"); InspectorBackend.registerCommand("Memory.getDOMNodeCount", [], ["domGroups", "strings"]); InspectorBackend.registerCommand("Memory.getProcessMemoryDistribution", [], ["distribution"]); InspectorBackend.registerPageDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Page"); InspectorBackend.registerEvent("Page.domContentEventFired", ["timestamp"]); InspectorBackend.registerEvent("Page.loadEventFired", ["timestamp"]); InspectorBackend.registerEvent("Page.frameNavigated", ["frame"]); InspectorBackend.registerEvent("Page.frameDetached", ["frameId"]); InspectorBackend.registerCommand("Page.enable", [], []); InspectorBackend.registerCommand("Page.disable", [], []); InspectorBackend.registerCommand("Page.addScriptToEvaluateOnLoad", [{"name": "scriptSource", "type": "string", "optional": false}], ["identifier"]); InspectorBackend.registerCommand("Page.removeScriptToEvaluateOnLoad", [{"name": "identifier", "type": "string", "optional": false}], []); InspectorBackend.registerCommand("Page.reload", [{"name": "ignoreCache", "type": "boolean", "optional": true}, {"name": "scriptToEvaluateOnLoad", "type": "string", "optional": true}], []); InspectorBackend.registerCommand("Page.navigate", [{"name": "url", "type": "string", "optional": false}], []); InspectorBackend.registerCommand("Page.getCookies", [], ["cookies", "cookiesString"]); InspectorBackend.registerCommand("Page.deleteCookie", [{"name": "cookieName", "type": "string", "optional": false}, {"name": "domain", "type": "string", "optional": false}], []); InspectorBackend.registerCommand("Page.getResourceTree", [], ["frameTree"]); InspectorBackend.registerCommand("Page.getResourceContent", [{"name": "frameId", "type": "string", "optional": false}, {"name": "url", "type": "string", "optional": false}], ["content", "base64Encoded"]); InspectorBackend.registerCommand("Page.searchInResource", [{"name": "frameId", "type": "string", "optional": false}, {"name": "url", "type": "string", "optional": false}, {"name": "query", "type": "string", "optional": false}, {"name": "caseSensitive", "type": "boolean", "optional": true}, {"name": "isRegex", "type": "boolean", "optional": true}], ["result"]); InspectorBackend.registerCommand("Page.searchInResources", [{"name": "text", "type": "string", "optional": false}, {"name": "caseSensitive", "type": "boolean", "optional": true}, {"name": "isRegex", "type": "boolean", "optional": true}], ["result"]); InspectorBackend.registerCommand("Page.setDocumentContent", [{"name": "frameId", "type": "string", "optional": false}, {"name": "html", "type": "string", "optional": false}], []); InspectorBackend.registerCommand("Page.canOverrideDeviceMetrics", [], ["result"]); InspectorBackend.registerCommand("Page.setDeviceMetricsOverride", [{"name": "width", "type": "number", "optional": false}, {"name": "height", "type": "number", "optional": false}, {"name": "fontScaleFactor", "type": "number", "optional": false}, {"name": "fitWindow", "type": "boolean", "optional": false}], []); InspectorBackend.registerCommand("Page.setShowPaintRects", [{"name": "result", "type": "boolean", "optional": false}], []); InspectorBackend.registerCommand("Page.getScriptExecutionStatus", [], ["result"]); InspectorBackend.registerCommand("Page.setScriptExecutionDisabled", [{"name": "value", "type": "boolean", "optional": false}], []); InspectorBackend.registerCommand("Page.setGeolocationOverride", [{"name": "latitude", "type": "number", "optional": true}, {"name": "longitude", "type": "number", "optional": true}, {"name": "accuracy", "type": "number", "optional": true}], []); InspectorBackend.registerCommand("Page.clearGeolocationOverride", [], []); InspectorBackend.registerCommand("Page.canOverrideGeolocation", [], ["result"]); InspectorBackend.registerCommand("Page.setDeviceOrientationOverride", [{"name": "alpha", "type": "number", "optional": false}, {"name": "beta", "type": "number", "optional": false}, {"name": "gamma", "type": "number", "optional": false}], []); InspectorBackend.registerCommand("Page.clearDeviceOrientationOverride", [], []); InspectorBackend.registerCommand("Page.canOverrideDeviceOrientation", [], ["result"]); InspectorBackend.registerCommand("Page.setTouchEmulationEnabled", [{"name": "enabled", "type": "boolean", "optional": false}], []); InspectorBackend.registerCommand("Page.getCompositingBordersVisible", [], ["result"]); InspectorBackend.registerCommand("Page.setCompositingBordersVisible", [{"name": "visible", "type": "boolean", "optional": false}], []); InspectorBackend.registerRuntimeDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Runtime"); InspectorBackend.registerEvent("Runtime.executionContextCreated", ["context"]); InspectorBackend.registerCommand("Runtime.evaluate", [{"name": "expression", "type": "string", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}, {"name": "includeCommandLineAPI", "type": "boolean", "optional": true}, {"name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true}, {"name": "contextId", "type": "number", "optional": true}, {"name": "returnByValue", "type": "boolean", "optional": true}, {"name": "generatePreview", "type": "boolean", "optional": true}], ["result", "wasThrown"]); InspectorBackend.registerCommand("Runtime.callFunctionOn", [{"name": "objectId", "type": "string", "optional": false}, {"name": "functionDeclaration", "type": "string", "optional": false}, {"name": "arguments", "type": "object", "optional": true}, {"name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true}, {"name": "returnByValue", "type": "boolean", "optional": true}, {"name": "generatePreview", "type": "boolean", "optional": true}], ["result", "wasThrown"]); InspectorBackend.registerCommand("Runtime.getProperties", [{"name": "objectId", "type": "string", "optional": false}, {"name": "ownProperties", "type": "boolean", "optional": true}], ["result", "internalProperties"]); InspectorBackend.registerCommand("Runtime.releaseObject", [{"name": "objectId", "type": "string", "optional": false}], []); InspectorBackend.registerCommand("Runtime.releaseObjectGroup", [{"name": "objectGroup", "type": "string", "optional": false}], []); InspectorBackend.registerCommand("Runtime.run", [], []); InspectorBackend.registerCommand("Runtime.enable", [], []); InspectorBackend.registerCommand("Runtime.disable", [], []); InspectorBackend.registerConsoleDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Console"); InspectorBackend.registerEvent("Console.messageAdded", ["message"]); InspectorBackend.registerEvent("Console.messageRepeatCountUpdated", ["count"]); InspectorBackend.registerEvent("Console.messagesCleared", []); InspectorBackend.registerCommand("Console.enable", [], []); InspectorBackend.registerCommand("Console.disable", [], []); InspectorBackend.registerCommand("Console.clearMessages", [], []); InspectorBackend.registerCommand("Console.setMonitoringXHREnabled", [{"name": "enabled", "type": "boolean", "optional": false}], []); InspectorBackend.registerCommand("Console.addInspectedNode", [{"name": "nodeId", "type": "number", "optional": false}], []); InspectorBackend.registerCommand("Console.addInspectedHeapObject", [{"name": "heapObjectId", "type": "number", "optional": false}], []); InspectorBackend.registerNetworkDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Network"); InspectorBackend.registerEvent("Network.requestWillBeSent", ["requestId", "frameId", "loaderId", "documentURL", "request", "timestamp", "initiator", "redirectResponse"]); InspectorBackend.registerEvent("Network.requestServedFromCache", ["requestId"]); InspectorBackend.registerEvent("Network.responseReceived", ["requestId", "frameId", "loaderId", "timestamp", "type", "response"]); InspectorBackend.registerEvent("Network.dataReceived", ["requestId", "timestamp", "dataLength", "encodedDataLength"]); InspectorBackend.registerEvent("Network.loadingFinished", ["requestId", "timestamp"]); InspectorBackend.registerEvent("Network.loadingFailed", ["requestId", "timestamp", "errorText", "canceled"]); InspectorBackend.registerEvent("Network.requestServedFromMemoryCache", ["requestId", "frameId", "loaderId", "documentURL", "timestamp", "initiator", "resource"]); InspectorBackend.registerEvent("Network.webSocketWillSendHandshakeRequest", ["requestId", "timestamp", "request"]); InspectorBackend.registerEvent("Network.webSocketHandshakeResponseReceived", ["requestId", "timestamp", "response"]); InspectorBackend.registerEvent("Network.webSocketCreated", ["requestId", "url"]); InspectorBackend.registerEvent("Network.webSocketClosed", ["requestId", "timestamp"]); InspectorBackend.registerEvent("Network.webSocketFrameReceived", ["requestId", "timestamp", "response"]); InspectorBackend.registerEvent("Network.webSocketFrameError", ["requestId", "timestamp", "errorMessage"]); InspectorBackend.registerEvent("Network.webSocketFrameSent", ["requestId", "timestamp", "response"]); InspectorBackend.registerCommand("Network.enable", [], []); InspectorBackend.registerCommand("Network.disable", [], []); InspectorBackend.registerCommand("Network.setUserAgentOverride", [{"name": "userAgent", "type": "string", "optional": false}], []); InspectorBackend.registerCommand("Network.setExtraHTTPHeaders", [{"name": "headers", "type": "object", "optional": false}], []); InspectorBackend.registerCommand("Network.getResponseBody", [{"name": "requestId", "type": "string", "optional": false}], ["body", "base64Encoded"]); InspectorBackend.registerCommand("Network.replayXHR", [{"name": "requestId", "type": "string", "optional": false}], []); InspectorBackend.registerCommand("Network.canClearBrowserCache", [], ["result"]); InspectorBackend.registerCommand("Network.clearBrowserCache", [], []); InspectorBackend.registerCommand("Network.canClearBrowserCookies", [], ["result"]); InspectorBackend.registerCommand("Network.clearBrowserCookies", [], []); InspectorBackend.registerCommand("Network.setCacheDisabled", [{"name": "cacheDisabled", "type": "boolean", "optional": false}], []); InspectorBackend.registerDatabaseDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Database"); InspectorBackend.registerEvent("Database.addDatabase", ["database"]); InspectorBackend.registerCommand("Database.enable", [], []); InspectorBackend.registerCommand("Database.disable", [], []); InspectorBackend.registerCommand("Database.getDatabaseTableNames", [{"name": "databaseId", "type": "string", "optional": false}], ["tableNames"]); InspectorBackend.registerCommand("Database.executeSQL", [{"name": "databaseId", "type": "string", "optional": false}, {"name": "query", "type": "string", "optional": false}], ["columnNames", "values", "sqlError"]); InspectorBackend.registerIndexedDBDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "IndexedDB"); InspectorBackend.registerCommand("IndexedDB.enable", [], []); InspectorBackend.registerCommand("IndexedDB.disable", [], []); InspectorBackend.registerCommand("IndexedDB.requestDatabaseNamesForFrame", [{"name": "frameId", "type": "string", "optional": false}], ["securityOriginWithDatabaseNames"]); InspectorBackend.registerCommand("IndexedDB.requestDatabase", [{"name": "frameId", "type": "string", "optional": false}, {"name": "databaseName", "type": "string", "optional": false}], ["databaseWithObjectStores"]); InspectorBackend.registerCommand("IndexedDB.requestData", [{"name": "frameId", "type": "string", "optional": false}, {"name": "databaseName", "type": "string", "optional": false}, {"name": "objectStoreName", "type": "string", "optional": false}, {"name": "indexName", "type": "string", "optional": false}, {"name": "skipCount", "type": "number", "optional": false}, {"name": "pageSize", "type": "number", "optional": false}, {"name": "keyRange", "type": "object", "optional": true}], ["objectStoreDataEntries", "hasMore"]); InspectorBackend.registerDOMStorageDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "DOMStorage"); InspectorBackend.registerEvent("DOMStorage.addDOMStorage", ["storage"]); InspectorBackend.registerEvent("DOMStorage.domStorageUpdated", ["storageId"]); InspectorBackend.registerCommand("DOMStorage.enable", [], []); InspectorBackend.registerCommand("DOMStorage.disable", [], []); InspectorBackend.registerCommand("DOMStorage.getDOMStorageEntries", [{"name": "storageId", "type": "string", "optional": false}], ["entries"]); InspectorBackend.registerCommand("DOMStorage.setDOMStorageItem", [{"name": "storageId", "type": "string", "optional": false}, {"name": "key", "type": "string", "optional": false}, {"name": "value", "type": "string", "optional": false}], ["success"]); InspectorBackend.registerCommand("DOMStorage.removeDOMStorageItem", [{"name": "storageId", "type": "string", "optional": false}, {"name": "key", "type": "string", "optional": false}], ["success"]); InspectorBackend.registerApplicationCacheDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "ApplicationCache"); InspectorBackend.registerEvent("ApplicationCache.applicationCacheStatusUpdated", ["frameId", "manifestURL", "status"]); InspectorBackend.registerEvent("ApplicationCache.networkStateUpdated", ["isNowOnline"]); InspectorBackend.registerCommand("ApplicationCache.getFramesWithManifests", [], ["frameIds"]); InspectorBackend.registerCommand("ApplicationCache.enable", [], []); InspectorBackend.registerCommand("ApplicationCache.getManifestForFrame", [{"name": "frameId", "type": "string", "optional": false}], ["manifestURL"]); InspectorBackend.registerCommand("ApplicationCache.getApplicationCacheForFrame", [{"name": "frameId", "type": "string", "optional": false}], ["applicationCache"]); InspectorBackend.registerFileSystemDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "FileSystem"); InspectorBackend.registerCommand("FileSystem.enable", [], []); InspectorBackend.registerCommand("FileSystem.disable", [], []); InspectorBackend.registerCommand("FileSystem.requestFileSystemRoot", [{"name": "origin", "type": "string", "optional": false}, {"name": "type", "type": "string", "optional": false}], ["errorCode", "root"]); InspectorBackend.registerCommand("FileSystem.requestDirectoryContent", [{"name": "url", "type": "string", "optional": false}], ["errorCode", "entries"]); InspectorBackend.registerCommand("FileSystem.requestMetadata", [{"name": "url", "type": "string", "optional": false}], ["errorCode", "metadata"]); InspectorBackend.registerCommand("FileSystem.requestFileContent", [{"name": "url", "type": "string", "optional": false}, {"name": "readAsText", "type": "boolean", "optional": false}, {"name": "start", "type": "number", "optional": true}, {"name": "end", "type": "number", "optional": true}, {"name": "charset", "type": "string", "optional": true}], ["errorCode", "content", "charset"]); InspectorBackend.registerCommand("FileSystem.deleteEntry", [{"name": "url", "type": "string", "optional": false}], ["errorCode"]); InspectorBackend.registerDOMDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "DOM"); InspectorBackend.registerEvent("DOM.documentUpdated", []); InspectorBackend.registerEvent("DOM.setChildNodes", ["parentId", "nodes"]); InspectorBackend.registerEvent("DOM.attributeModified", ["nodeId", "name", "value"]); InspectorBackend.registerEvent("DOM.attributeRemoved", ["nodeId", "name"]); InspectorBackend.registerEvent("DOM.inlineStyleInvalidated", ["nodeIds"]); InspectorBackend.registerEvent("DOM.characterDataModified", ["nodeId", "characterData"]); InspectorBackend.registerEvent("DOM.childNodeCountUpdated", ["nodeId", "childNodeCount"]); InspectorBackend.registerEvent("DOM.childNodeInserted", ["parentNodeId", "previousNodeId", "node"]); InspectorBackend.registerEvent("DOM.childNodeRemoved", ["parentNodeId", "nodeId"]); InspectorBackend.registerEvent("DOM.shadowRootPushed", ["hostId", "root"]); InspectorBackend.registerEvent("DOM.shadowRootPopped", ["hostId", "rootId"]); InspectorBackend.registerCommand("DOM.getDocument", [], ["root"]); InspectorBackend.registerCommand("DOM.requestChildNodes", [{"name": "nodeId", "type": "number", "optional": false}], []); InspectorBackend.registerCommand("DOM.querySelector", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "selector", "type": "string", "optional": false}], ["nodeId"]); InspectorBackend.registerCommand("DOM.querySelectorAll", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "selector", "type": "string", "optional": false}], ["nodeIds"]); InspectorBackend.registerCommand("DOM.setNodeName", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "name", "type": "string", "optional": false}], ["nodeId"]); InspectorBackend.registerCommand("DOM.setNodeValue", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "value", "type": "string", "optional": false}], []); InspectorBackend.registerCommand("DOM.removeNode", [{"name": "nodeId", "type": "number", "optional": false}], []); InspectorBackend.registerCommand("DOM.setAttributeValue", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "name", "type": "string", "optional": false}, {"name": "value", "type": "string", "optional": false}], []); InspectorBackend.registerCommand("DOM.setAttributesAsText", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "text", "type": "string", "optional": false}, {"name": "name", "type": "string", "optional": true}], []); InspectorBackend.registerCommand("DOM.removeAttribute", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "name", "type": "string", "optional": false}], []); InspectorBackend.registerCommand("DOM.getEventListenersForNode", [{"name": "nodeId", "type": "number", "optional": false}], ["listeners"]); InspectorBackend.registerCommand("DOM.getOuterHTML", [{"name": "nodeId", "type": "number", "optional": false}], ["outerHTML"]); InspectorBackend.registerCommand("DOM.setOuterHTML", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "outerHTML", "type": "string", "optional": false}], []); InspectorBackend.registerCommand("DOM.performSearch", [{"name": "query", "type": "string", "optional": false}], ["searchId", "resultCount"]); InspectorBackend.registerCommand("DOM.getSearchResults", [{"name": "searchId", "type": "string", "optional": false}, {"name": "fromIndex", "type": "number", "optional": false}, {"name": "toIndex", "type": "number", "optional": false}], ["nodeIds"]); InspectorBackend.registerCommand("DOM.discardSearchResults", [{"name": "searchId", "type": "string", "optional": false}], []); InspectorBackend.registerCommand("DOM.requestNode", [{"name": "objectId", "type": "string", "optional": false}], ["nodeId"]); InspectorBackend.registerCommand("DOM.setInspectModeEnabled", [{"name": "enabled", "type": "boolean", "optional": false}, {"name": "highlightConfig", "type": "object", "optional": true}], []); InspectorBackend.registerCommand("DOM.highlightRect", [{"name": "x", "type": "number", "optional": false}, {"name": "y", "type": "number", "optional": false}, {"name": "width", "type": "number", "optional": false}, {"name": "height", "type": "number", "optional": false}, {"name": "color", "type": "object", "optional": true}, {"name": "outlineColor", "type": "object", "optional": true}], []); InspectorBackend.registerCommand("DOM.highlightNode", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "highlightConfig", "type": "object", "optional": false}], []); InspectorBackend.registerCommand("DOM.hideHighlight", [], []); InspectorBackend.registerCommand("DOM.highlightFrame", [{"name": "frameId", "type": "string", "optional": false}, {"name": "contentColor", "type": "object", "optional": true}, {"name": "contentOutlineColor", "type": "object", "optional": true}], []); InspectorBackend.registerCommand("DOM.pushNodeByPathToFrontend", [{"name": "path", "type": "string", "optional": false}], ["nodeId"]); InspectorBackend.registerCommand("DOM.resolveNode", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}], ["object"]); InspectorBackend.registerCommand("DOM.getAttributes", [{"name": "nodeId", "type": "number", "optional": false}], ["attributes"]); InspectorBackend.registerCommand("DOM.moveTo", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "targetNodeId", "type": "number", "optional": false}, {"name": "insertBeforeNodeId", "type": "number", "optional": true}], ["nodeId"]); InspectorBackend.registerCommand("DOM.undo", [], []); InspectorBackend.registerCommand("DOM.redo", [], []); InspectorBackend.registerCommand("DOM.markUndoableState", [], []); InspectorBackend.registerCSSDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "CSS"); InspectorBackend.registerEvent("CSS.mediaQueryResultChanged", []); InspectorBackend.registerEvent("CSS.styleSheetChanged", ["styleSheetId"]); InspectorBackend.registerEvent("CSS.namedFlowCreated", ["namedFlow"]); InspectorBackend.registerEvent("CSS.namedFlowRemoved", ["documentNodeId", "flowName"]); InspectorBackend.registerEvent("CSS.regionLayoutUpdated", ["namedFlow"]); InspectorBackend.registerCommand("CSS.enable", [], []); InspectorBackend.registerCommand("CSS.disable", [], []); InspectorBackend.registerCommand("CSS.getMatchedStylesForNode", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "includePseudo", "type": "boolean", "optional": true}, {"name": "includeInherited", "type": "boolean", "optional": true}], ["matchedCSSRules", "pseudoElements", "inherited"]); InspectorBackend.registerCommand("CSS.getInlineStylesForNode", [{"name": "nodeId", "type": "number", "optional": false}], ["inlineStyle", "attributesStyle"]); InspectorBackend.registerCommand("CSS.getComputedStyleForNode", [{"name": "nodeId", "type": "number", "optional": false}], ["computedStyle"]); InspectorBackend.registerCommand("CSS.getAllStyleSheets", [], ["headers"]); InspectorBackend.registerCommand("CSS.getStyleSheet", [{"name": "styleSheetId", "type": "string", "optional": false}], ["styleSheet"]); InspectorBackend.registerCommand("CSS.getStyleSheetText", [{"name": "styleSheetId", "type": "string", "optional": false}], ["text"]); InspectorBackend.registerCommand("CSS.setStyleSheetText", [{"name": "styleSheetId", "type": "string", "optional": false}, {"name": "text", "type": "string", "optional": false}], []); InspectorBackend.registerCommand("CSS.setPropertyText", [{"name": "styleId", "type": "object", "optional": false}, {"name": "propertyIndex", "type": "number", "optional": false}, {"name": "text", "type": "string", "optional": false}, {"name": "overwrite", "type": "boolean", "optional": false}], ["style"]); InspectorBackend.registerCommand("CSS.toggleProperty", [{"name": "styleId", "type": "object", "optional": false}, {"name": "propertyIndex", "type": "number", "optional": false}, {"name": "disable", "type": "boolean", "optional": false}], ["style"]); InspectorBackend.registerCommand("CSS.setRuleSelector", [{"name": "ruleId", "type": "object", "optional": false}, {"name": "selector", "type": "string", "optional": false}], ["rule"]); InspectorBackend.registerCommand("CSS.addRule", [{"name": "contextNodeId", "type": "number", "optional": false}, {"name": "selector", "type": "string", "optional": false}], ["rule"]); InspectorBackend.registerCommand("CSS.getSupportedCSSProperties", [], ["cssProperties"]); InspectorBackend.registerCommand("CSS.forcePseudoState", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "forcedPseudoClasses", "type": "object", "optional": false}], []); InspectorBackend.registerCommand("CSS.startSelectorProfiler", [], []); InspectorBackend.registerCommand("CSS.stopSelectorProfiler", [], ["profile"]); InspectorBackend.registerCommand("CSS.getNamedFlowCollection", [{"name": "documentNodeId", "type": "number", "optional": false}], ["namedFlows"]); InspectorBackend.registerTimelineDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Timeline"); InspectorBackend.registerEvent("Timeline.eventRecorded", ["record"]); InspectorBackend.registerCommand("Timeline.start", [{"name": "maxCallStackDepth", "type": "number", "optional": true}], []); InspectorBackend.registerCommand("Timeline.stop", [], []); InspectorBackend.registerCommand("Timeline.setIncludeMemoryDetails", [{"name": "enabled", "type": "boolean", "optional": false}], []); InspectorBackend.registerCommand("Timeline.supportsFrameInstrumentation", [], ["result"]); InspectorBackend.registerCommand("Timeline.canMonitorMainThread", [], ["result"]); InspectorBackend.registerDebuggerDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Debugger"); InspectorBackend.registerEvent("Debugger.globalObjectCleared", []); InspectorBackend.registerEvent("Debugger.scriptParsed", ["scriptId", "url", "startLine", "startColumn", "endLine", "endColumn", "isContentScript", "sourceMapURL", "hasSourceURL"]); InspectorBackend.registerEvent("Debugger.scriptFailedToParse", ["url", "scriptSource", "startLine", "errorLine", "errorMessage"]); InspectorBackend.registerEvent("Debugger.breakpointResolved", ["breakpointId", "location"]); InspectorBackend.registerEvent("Debugger.paused", ["callFrames", "reason", "data"]); InspectorBackend.registerEvent("Debugger.resumed", []); InspectorBackend.registerCommand("Debugger.causesRecompilation", [], ["result"]); InspectorBackend.registerCommand("Debugger.supportsSeparateScriptCompilationAndExecution", [], ["result"]); InspectorBackend.registerCommand("Debugger.enable", [], []); InspectorBackend.registerCommand("Debugger.disable", [], []); InspectorBackend.registerCommand("Debugger.setBreakpointsActive", [{"name": "active", "type": "boolean", "optional": false}], []); InspectorBackend.registerCommand("Debugger.setBreakpointByUrl", [{"name": "lineNumber", "type": "number", "optional": false}, {"name": "url", "type": "string", "optional": true}, {"name": "urlRegex", "type": "string", "optional": true}, {"name": "columnNumber", "type": "number", "optional": true}, {"name": "condition", "type": "string", "optional": true}], ["breakpointId", "locations"]); InspectorBackend.registerCommand("Debugger.setBreakpoint", [{"name": "location", "type": "object", "optional": false}, {"name": "condition", "type": "string", "optional": true}], ["breakpointId", "actualLocation"]); InspectorBackend.registerCommand("Debugger.removeBreakpoint", [{"name": "breakpointId", "type": "string", "optional": false}], []); InspectorBackend.registerCommand("Debugger.continueToLocation", [{"name": "location", "type": "object", "optional": false}], []); InspectorBackend.registerCommand("Debugger.stepOver", [], []); InspectorBackend.registerCommand("Debugger.stepInto", [], []); InspectorBackend.registerCommand("Debugger.stepOut", [], []); InspectorBackend.registerCommand("Debugger.pause", [], []); InspectorBackend.registerCommand("Debugger.resume", [], []); InspectorBackend.registerCommand("Debugger.searchInContent", [{"name": "scriptId", "type": "string", "optional": false}, {"name": "query", "type": "string", "optional": false}, {"name": "caseSensitive", "type": "boolean", "optional": true}, {"name": "isRegex", "type": "boolean", "optional": true}], ["result"]); InspectorBackend.registerCommand("Debugger.canSetScriptSource", [], ["result"]); InspectorBackend.registerCommand("Debugger.setScriptSource", [{"name": "scriptId", "type": "string", "optional": false}, {"name": "scriptSource", "type": "string", "optional": false}, {"name": "preview", "type": "boolean", "optional": true}], ["callFrames", "result"]); InspectorBackend.registerCommand("Debugger.restartFrame", [{"name": "callFrameId", "type": "string", "optional": false}], ["callFrames", "result"]); InspectorBackend.registerCommand("Debugger.getScriptSource", [{"name": "scriptId", "type": "string", "optional": false}], ["scriptSource"]); InspectorBackend.registerCommand("Debugger.getFunctionDetails", [{"name": "functionId", "type": "string", "optional": false}], ["details"]); InspectorBackend.registerCommand("Debugger.setPauseOnExceptions", [{"name": "state", "type": "string", "optional": false}], []); InspectorBackend.registerCommand("Debugger.evaluateOnCallFrame", [{"name": "callFrameId", "type": "string", "optional": false}, {"name": "expression", "type": "string", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}, {"name": "includeCommandLineAPI", "type": "boolean", "optional": true}, {"name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true}, {"name": "returnByValue", "type": "boolean", "optional": true}, {"name": "generatePreview", "type": "boolean", "optional": true}], ["result", "wasThrown"]); InspectorBackend.registerCommand("Debugger.compileScript", [{"name": "expression", "type": "string", "optional": false}, {"name": "sourceURL", "type": "string", "optional": false}], ["scriptId", "syntaxErrorMessage"]); InspectorBackend.registerCommand("Debugger.runScript", [{"name": "scriptId", "type": "string", "optional": false}, {"name": "contextId", "type": "number", "optional": true}, {"name": "objectGroup", "type": "string", "optional": true}, {"name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true}], ["result", "wasThrown"]); InspectorBackend.registerCommand("Debugger.setOverlayMessage", [{"name": "message", "type": "string", "optional": true}], []); InspectorBackend.registerCommand("DOMDebugger.setDOMBreakpoint", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "type", "type": "string", "optional": false}], []); InspectorBackend.registerCommand("DOMDebugger.removeDOMBreakpoint", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "type", "type": "string", "optional": false}], []); InspectorBackend.registerCommand("DOMDebugger.setEventListenerBreakpoint", [{"name": "eventName", "type": "string", "optional": false}], []); InspectorBackend.registerCommand("DOMDebugger.removeEventListenerBreakpoint", [{"name": "eventName", "type": "string", "optional": false}], []); InspectorBackend.registerCommand("DOMDebugger.setInstrumentationBreakpoint", [{"name": "eventName", "type": "string", "optional": false}], []); InspectorBackend.registerCommand("DOMDebugger.removeInstrumentationBreakpoint", [{"name": "eventName", "type": "string", "optional": false}], []); InspectorBackend.registerCommand("DOMDebugger.setXHRBreakpoint", [{"name": "url", "type": "string", "optional": false}], []); InspectorBackend.registerCommand("DOMDebugger.removeXHRBreakpoint", [{"name": "url", "type": "string", "optional": false}], []); InspectorBackend.registerProfilerDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Profiler"); InspectorBackend.registerEvent("Profiler.addProfileHeader", ["header"]); InspectorBackend.registerEvent("Profiler.addHeapSnapshotChunk", ["uid", "chunk"]); InspectorBackend.registerEvent("Profiler.finishHeapSnapshot", ["uid"]); InspectorBackend.registerEvent("Profiler.setRecordingProfile", ["isProfiling"]); InspectorBackend.registerEvent("Profiler.resetProfiles", []); InspectorBackend.registerEvent("Profiler.reportHeapSnapshotProgress", ["done", "total"]); InspectorBackend.registerCommand("Profiler.causesRecompilation", [], ["result"]); InspectorBackend.registerCommand("Profiler.isSampling", [], ["result"]); InspectorBackend.registerCommand("Profiler.hasHeapProfiler", [], ["result"]); InspectorBackend.registerCommand("Profiler.enable", [], []); InspectorBackend.registerCommand("Profiler.disable", [], []); InspectorBackend.registerCommand("Profiler.start", [], []); InspectorBackend.registerCommand("Profiler.stop", [], []); InspectorBackend.registerCommand("Profiler.getProfileHeaders", [], ["headers"]); InspectorBackend.registerCommand("Profiler.getProfile", [{"name": "type", "type": "string", "optional": false}, {"name": "uid", "type": "number", "optional": false}], ["profile"]); InspectorBackend.registerCommand("Profiler.removeProfile", [{"name": "type", "type": "string", "optional": false}, {"name": "uid", "type": "number", "optional": false}], []); InspectorBackend.registerCommand("Profiler.clearProfiles", [], []); InspectorBackend.registerCommand("Profiler.takeHeapSnapshot", [], []); InspectorBackend.registerCommand("Profiler.collectGarbage", [], []); InspectorBackend.registerCommand("Profiler.getObjectByHeapObjectId", [{"name": "objectId", "type": "string", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}], ["result"]); InspectorBackend.registerCommand("Profiler.getHeapObjectId", [{"name": "objectId", "type": "string", "optional": false}], ["heapSnapshotObjectId"]); InspectorBackend.registerWorkerDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Worker"); InspectorBackend.registerEvent("Worker.workerCreated", ["workerId", "url", "inspectorConnected"]); InspectorBackend.registerEvent("Worker.workerTerminated", ["workerId"]); InspectorBackend.registerEvent("Worker.dispatchMessageFromWorker", ["workerId", "message"]); InspectorBackend.registerEvent("Worker.disconnectedFromWorker", []); InspectorBackend.registerCommand("Worker.enable", [], []); InspectorBackend.registerCommand("Worker.disable", [], []); InspectorBackend.registerCommand("Worker.sendMessageToWorker", [{"name": "workerId", "type": "number", "optional": false}, {"name": "message", "type": "object", "optional": false}], []); InspectorBackend.registerCommand("Worker.connectToWorker", [{"name": "workerId", "type": "number", "optional": false}], []); InspectorBackend.registerCommand("Worker.disconnectFromWorker", [{"name": "workerId", "type": "number", "optional": false}], []); InspectorBackend.registerCommand("Worker.setAutoconnectToWorkers", [{"name": "value", "type": "boolean", "optional": false}], []); InspectorBackend.registerCanvasDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Canvas"); InspectorBackend.registerCommand("Canvas.enable", [], []); InspectorBackend.registerCommand("Canvas.disable", [], []); InspectorBackend.registerCommand("Canvas.dropTraceLog", [{"name": "traceLogId", "type": "string", "optional": false}], []); InspectorBackend.registerCommand("Canvas.captureFrame", [], ["traceLogId"]); InspectorBackend.registerCommand("Canvas.getTraceLog", [{"name": "traceLogId", "type": "string", "optional": false}], ["traceLog"]); InspectorBackend.registerCommand("Canvas.replayTraceLog", [{"name": "traceLogId", "type": "string", "optional": false}, {"name": "stepNo", "type": "number", "optional": false}], ["screenshotDataUrl"]); if (!window.InspectorExtensionRegistry) { WebInspector.InspectorExtensionRegistryStub = function() { } WebInspector.InspectorExtensionRegistryStub.prototype = { getExtensionsAsync: function() { } } var InspectorExtensionRegistry = new WebInspector.InspectorExtensionRegistryStub(); } var InspectorFrontendAPI = { _pendingCommands: [], isDebuggingEnabled: function() { return WebInspector.debuggerModel.debuggerEnabled(); }, setDebuggingEnabled: function(enabled) { if (enabled) { WebInspector.debuggerModel.enableDebugger(); WebInspector.showPanel("scripts"); } else WebInspector.debuggerModel.disableDebugger(); }, isTimelineProfilingEnabled: function() { return WebInspector.panels.timeline && WebInspector.panels.timeline.timelineProfilingEnabled; }, setTimelineProfilingEnabled: function(enabled) { WebInspector.showPanel("timeline").setTimelineProfilingEnabled(enabled); }, isProfilingJavaScript: function() { return WebInspector.panels.profiles && WebInspector.CPUProfileType.instance && WebInspector.CPUProfileType.instance.isRecordingProfile(); }, startProfilingJavaScript: function() { WebInspector.showPanel("profiles").enableProfiler(); if (WebInspector.CPUProfileType.instance) WebInspector.CPUProfileType.instance.startRecordingProfile(); }, stopProfilingJavaScript: function() { WebInspector.showPanel("profiles"); if (WebInspector.CPUProfileType.instance) WebInspector.CPUProfileType.instance.stopRecordingProfile(); }, setAttachedWindow: function(side) { }, setDockSide: function(side) { if (WebInspector.dockController) WebInspector.dockController.setDockSide(side); }, showConsole: function() { WebInspector.showPanel("console"); }, showMainResourceForFrame: function(frameId) { }, showResources: function() { WebInspector.showPanel("resources"); }, setDockingUnavailable: function(unavailable) { WebInspector.setDockingUnavailable(unavailable); }, enterInspectElementMode: function() { WebInspector.toggleSearchingForNode(); }, savedURL: function(url) { WebInspector.fileManager.savedURL(url); }, appendedToURL: function(url) { WebInspector.fileManager.appendedToURL(url); }, setToolbarColors: function(backgroundColor, color) { WebInspector.setToolbarColors(backgroundColor, color); }, evaluateForTest: function(callId, script) { WebInspector.evaluateForTestInFrontend(callId, script); }, dispatch: function(signature) { if (InspectorFrontendAPI._isLoaded) { var methodName = signature.shift(); return InspectorFrontendAPI[methodName].apply(InspectorFrontendAPI, signature); } InspectorFrontendAPI._pendingCommands.push(signature); }, dispatchQueryParameters: function() { if ("dispatch" in WebInspector.queryParamsObject) InspectorFrontendAPI.dispatch(JSON.parse(window.decodeURI(WebInspector.queryParamsObject["dispatch"]))); }, loadTimelineFromURL: function(url) { WebInspector.showPanel("timeline").loadFromURL(url); }, loadCompleted: function() { InspectorFrontendAPI._isLoaded = true; for (var i = 0; i < InspectorFrontendAPI._pendingCommands.length; ++i) InspectorFrontendAPI.dispatch(InspectorFrontendAPI._pendingCommands[i]); InspectorFrontendAPI._pendingCommands = []; if (window.opener) window.opener.postMessage(["loadCompleted"], "*"); }, contextMenuItemSelected: function(id) { WebInspector.contextMenuItemSelected(id); }, contextMenuCleared: function() { WebInspector.contextMenuCleared(); }, dispatchMessageAsync: function(messageObject) { WebInspector.dispatch(messageObject); }, dispatchMessage: function(messageObject) { InspectorBackend.dispatch(messageObject); } } if (window.opener) { function onMessageFromOpener(event) { if (event.source === window.opener) InspectorFrontendAPI.dispatch(event.data); } window.addEventListener("message", onMessageFromOpener, true); } WebInspector.Object = function() { } WebInspector.Object.prototype = { addEventListener: function(eventType, listener, thisObject) { console.assert(listener); if (!this._listeners) this._listeners = {}; if (!this._listeners[eventType]) this._listeners[eventType] = []; this._listeners[eventType].push({ thisObject: thisObject, listener: listener }); }, removeEventListener: function(eventType, listener, thisObject) { console.assert(listener); if (!this._listeners || !this._listeners[eventType]) return; var listeners = this._listeners[eventType]; for (var i = 0; i < listeners.length; ++i) { if (listener && listeners[i].listener === listener && listeners[i].thisObject === thisObject) listeners.splice(i, 1); else if (!listener && thisObject && listeners[i].thisObject === thisObject) listeners.splice(i, 1); } if (!listeners.length) delete this._listeners[eventType]; }, removeAllListeners: function() { delete this._listeners; }, hasEventListeners: function(eventType) { if (!this._listeners || !this._listeners[eventType]) return false; return true; }, dispatchEventToListeners: function(eventType, eventData) { if (!this._listeners || !this._listeners[eventType]) return false; var event = new WebInspector.Event(this, eventType, eventData); var listeners = this._listeners[eventType].slice(0); for (var i = 0; i < listeners.length; ++i) { listeners[i].listener.call(listeners[i].thisObject, event); if (event._stoppedPropagation) break; } return event.defaultPrevented; } } WebInspector.Event = function(target, type, data) { this.target = target; this.type = type; this.data = data; this.defaultPrevented = false; this._stoppedPropagation = false; } WebInspector.Event.prototype = { stopPropagation: function() { this._stoppedPropagation = true; }, preventDefault: function() { this.defaultPrevented = true; }, consume: function(preventDefault) { this.stopPropagation(); if (preventDefault) this.preventDefault(); } } WebInspector.notifications = new WebInspector.Object(); var Preferences = { maxInlineTextChildLength: 80, minConsoleHeight: 75, minSidebarWidth: 100, minElementsSidebarWidth: 200, minScriptsSidebarWidth: 200, styleRulesExpandedState: {}, showMissingLocalizedStrings: false, useLowerCaseMenuTitlesOnWindows: false, sharedWorkersDebugNote: undefined, localizeUI: true, exposeDisableCache: false, applicationTitle: "Web Inspector - %s", showDockToRight: false, exposeFileSystemInspection: false, experimentsEnabled: true } var Capabilities = { samplingCPUProfiler: false, debuggerCausesRecompilation: true, separateScriptCompilationAndExecutionEnabled: false, profilerCausesRecompilation: true, heapProfilerPresent: false, canOverrideDeviceMetrics: false, timelineSupportsFrameInstrumentation: false, timelineCanMonitorMainThread: false, canOverrideGeolocation: false, canOverrideDeviceOrientation: false, } WebInspector.Settings = function() { this._eventSupport = new WebInspector.Object(); this.colorFormat = this.createSetting("colorFormat", "original"); this.consoleHistory = this.createSetting("consoleHistory", []); this.debuggerEnabled = this.createSetting("debuggerEnabled", false); this.domWordWrap = this.createSetting("domWordWrap", true); this.profilerEnabled = this.createSetting("profilerEnabled", false); this.eventListenersFilter = this.createSetting("eventListenersFilter", "all"); this.lastActivePanel = this.createSetting("lastActivePanel", "elements"); this.lastViewedScriptFile = this.createSetting("lastViewedScriptFile", "application"); this.monitoringXHREnabled = this.createSetting("monitoringXHREnabled", false); this.preserveConsoleLog = this.createSetting("preserveConsoleLog", false); this.resourcesLargeRows = this.createSetting("resourcesLargeRows", true); this.resourcesSortOptions = this.createSetting("resourcesSortOptions", {timeOption: "responseTime", sizeOption: "transferSize"}); this.resourceViewTab = this.createSetting("resourceViewTab", "preview"); this.showInheritedComputedStyleProperties = this.createSetting("showInheritedComputedStyleProperties", false); this.showUserAgentStyles = this.createSetting("showUserAgentStyles", true); this.watchExpressions = this.createSetting("watchExpressions", []); this.breakpoints = this.createSetting("breakpoints", []); this.eventListenerBreakpoints = this.createSetting("eventListenerBreakpoints", []); this.domBreakpoints = this.createSetting("domBreakpoints", []); this.xhrBreakpoints = this.createSetting("xhrBreakpoints", []); this.sourceMapsEnabled = this.createSetting("sourceMapsEnabled", false); this.cacheDisabled = this.createSetting("cacheDisabled", false); this.overrideUserAgent = this.createSetting("overrideUserAgent", ""); this.userAgent = this.createSetting("userAgent", ""); this.deviceMetrics = this.createSetting("deviceMetrics", ""); this.deviceFitWindow = this.createSetting("deviceFitWindow", false); this.showScriptFolders = this.createSetting("showScriptFolders", true); this.emulateTouchEvents = this.createSetting("emulateTouchEvents", false); this.showPaintRects = this.createSetting("showPaintRects", false); this.showShadowDOM = this.createSetting("showShadowDOM", false); this.zoomLevel = this.createSetting("zoomLevel", 0); this.savedURLs = this.createSetting("savedURLs", {}); this.javaScriptDisabled = this.createSetting("javaScriptDisabled", false); this.geolocationOverride = this.createSetting("geolocationOverride", ""); this.deviceOrientationOverride = this.createSetting("deviceOrientationOverride", ""); this.showHeapSnapshotObjectsHiddenProperties = this.createSetting("showHeaSnapshotObjectsHiddenProperties", false); this.searchInContentScripts = this.createSetting("searchInContentScripts", false); this.textEditorIndent = this.createSetting("textEditorIndent", " "); this.lastDockState = this.createSetting("lastDockState", ""); this.cssReloadEnabled = this.createSetting("cssReloadEnabled", false); this.cssReloadTimeout = this.createSetting("cssReloadTimeout", 1000); this.showCpuOnTimelineRuler = this.createSetting("showCpuOnTimelineRuler", false); this.showMetricsRulers = this.createSetting("showMetricsRulers", false); if (this.breakpoints.get().length > 500000) this.breakpoints.set([]); } WebInspector.Settings.prototype = { createSetting: function(key, defaultValue) { return new WebInspector.Setting(key, defaultValue, this._eventSupport); } } WebInspector.Setting = function(name, defaultValue, eventSupport) { this._name = name; this._defaultValue = defaultValue; this._eventSupport = eventSupport; } WebInspector.Setting.prototype = { addChangeListener: function(listener, thisObject) { this._eventSupport.addEventListener(this._name, listener, thisObject); }, removeChangeListener: function(listener, thisObject) { this._eventSupport.removeEventListener(this._name, listener, thisObject); }, get name() { return this._name; }, get: function() { if (typeof this._value !== "undefined") return this._value; this._value = this._defaultValue; if (window.localStorage != null && this._name in window.localStorage) { try { this._value = JSON.parse(window.localStorage[this._name]); } catch(e) { window.localStorage.removeItem(this._name); } } return this._value; }, set: function(value) { this._value = value; if (window.localStorage != null) { try { window.localStorage[this._name] = JSON.stringify(value); } catch(e) { console.error("Error saving setting with name:" + this._name); } } this._eventSupport.dispatchEventToListeners(this._name, value); } } WebInspector.ExperimentsSettings = function() { this._setting = WebInspector.settings.createSetting("experiments", {}); this._experiments = []; this._enabledForTest = {}; this.snippetsSupport = this._createExperiment("snippetsSupport", "Snippets support"); this.nativeMemorySnapshots = this._createExperiment("nativeMemorySnapshots", "Native memory profiling"); this.liveNativeMemoryChart = this._createExperiment("liveNativeMemoryChart", "Live native memory chart"); this.fileSystemInspection = this._createExperiment("fileSystemInspection", "FileSystem inspection"); this.canvasInspection = this._createExperiment("canvasInspection ", "Canvas inspection"); this.sass = this._createExperiment("sass", "Support for SASS"); this.codemirror = this._createExperiment("codemirror", "Use CodeMirror editor"); this.cssRegions = this._createExperiment("cssRegions", "CSS Regions Support"); this._cleanUpSetting(); } WebInspector.ExperimentsSettings.prototype = { get experiments() { return this._experiments.slice(); }, get experimentsEnabled() { return Preferences.experimentsEnabled || ("experiments" in WebInspector.queryParamsObject); }, _createExperiment: function(experimentName, experimentTitle) { var experiment = new WebInspector.Experiment(this, experimentName, experimentTitle); this._experiments.push(experiment); return experiment; }, isEnabled: function(experimentName) { if (this._enabledForTest[experimentName]) return true; if (!this.experimentsEnabled) return false; var experimentsSetting = this._setting.get(); return experimentsSetting[experimentName]; }, setEnabled: function(experimentName, enabled) { var experimentsSetting = this._setting.get(); experimentsSetting[experimentName] = enabled; this._setting.set(experimentsSetting); }, _enableForTest: function(experimentName) { this._enabledForTest[experimentName] = true; }, _cleanUpSetting: function() { var experimentsSetting = this._setting.get(); var cleanedUpExperimentSetting = {}; for (var i = 0; i < this._experiments.length; ++i) { var experimentName = this._experiments[i].name; if (experimentsSetting[experimentName]) cleanedUpExperimentSetting[experimentName] = true; } this._setting.set(cleanedUpExperimentSetting); } } WebInspector.Experiment = function(experimentsSettings, name, title) { this._name = name; this._title = title; this._experimentsSettings = experimentsSettings; } WebInspector.Experiment.prototype = { get name() { return this._name; }, get title() { return this._title; }, isEnabled: function() { return this._experimentsSettings.isEnabled(this._name); }, setEnabled: function(enabled) { return this._experimentsSettings.setEnabled(this._name, enabled); }, enableForTest: function() { this._experimentsSettings._enableForTest(this._name); } } WebInspector.settings = new WebInspector.Settings(); WebInspector.experimentsSettings = new WebInspector.ExperimentsSettings(); WebInspector.View = function() { this.element = document.createElement("div"); this.element.__view = this; this._visible = true; this._isRoot = false; this._isShowing = false; this._children = []; this._hideOnDetach = false; this._cssFiles = []; } WebInspector.View._cssFileToVisibleViewCount = {}; WebInspector.View._cssFileToStyleElement = {}; WebInspector.View.prototype = { markAsRoot: function() { this._isRoot = true; }, isShowing: function() { return this._isShowing; }, setHideOnDetach: function() { this._hideOnDetach = true; }, _parentIsShowing: function() { return this._isRoot || (this._parentView && this._parentView.isShowing()); }, _callOnVisibleChildren: function(method) { for (var i = 0; i < this._children.length; ++i) if (this._children[i]._visible) method.call(this._children[i]); }, _processWillShow: function() { this._loadCSSIfNeeded(); this._callOnVisibleChildren(this._processWillShow); }, _processWasShown: function() { this._isShowing = true; this.restoreScrollPositions(); this.wasShown(); this.onResize(); this._callOnVisibleChildren(this._processWasShown); }, _processWillHide: function() { this.storeScrollPositions(); this._callOnVisibleChildren(this._processWillHide); this.willHide(); this._isShowing = false; }, _processWasHidden: function() { this._disableCSSIfNeeded(); this._callOnVisibleChildren(this._processWasHidden); }, _processOnResize: function() { if (!this.isShowing()) return; this.onResize(); this._callOnVisibleChildren(this._processOnResize); }, wasShown: function() { }, willHide: function() { }, onResize: function() { }, show: function(parentElement, insertBefore) { WebInspector.View._assert(parentElement, "Attempt to attach view with no parent element"); if (this.element.parentElement !== parentElement) { var currentParent = parentElement; while (currentParent && !currentParent.__view) currentParent = currentParent.parentElement; if (currentParent) { this._parentView = currentParent.__view; this._parentView._children.push(this); this._isRoot = false; } else WebInspector.View._assert(this._isRoot, "Attempt to attach view to orphan node"); } else if (this._visible) return; this._visible = true; if (this._parentIsShowing()) this._processWillShow(); this.element.addStyleClass("visible"); if (this.element.parentElement !== parentElement) { WebInspector.View._incrementViewCounter(parentElement, this.element); if (insertBefore) WebInspector.View._originalInsertBefore.call(parentElement, this.element, insertBefore); else WebInspector.View._originalAppendChild.call(parentElement, this.element); } if (this._parentIsShowing()) this._processWasShown(); }, detach: function(overrideHideOnDetach) { var parentElement = this.element.parentElement; if (!parentElement) return; if (this._parentIsShowing()) this._processWillHide(); if (this._hideOnDetach && !overrideHideOnDetach) { this.element.removeStyleClass("visible"); this._visible = false; if (this._parentIsShowing()) this._processWasHidden(); return; } WebInspector.View._decrementViewCounter(parentElement, this.element); WebInspector.View._originalRemoveChild.call(parentElement, this.element); this._visible = false; if (this._parentIsShowing()) this._processWasHidden(); if (this._parentView) { var childIndex = this._parentView._children.indexOf(this); WebInspector.View._assert(childIndex >= 0, "Attempt to remove non-child view"); this._parentView._children.splice(childIndex, 1); this._parentView = null; } else WebInspector.View._assert(this._isRoot, "Removing non-root view from DOM"); }, detachChildViews: function() { var children = this._children.slice(); for (var i = 0; i < children.length; ++i) children[i].detach(); }, elementsToRestoreScrollPositionsFor: function() { return [this.element]; }, storeScrollPositions: function() { var elements = this.elementsToRestoreScrollPositionsFor(); for (var i = 0; i < elements.length; ++i) { var container = elements[i]; container._scrollTop = container.scrollTop; container._scrollLeft = container.scrollLeft; } }, restoreScrollPositions: function() { var elements = this.elementsToRestoreScrollPositionsFor(); for (var i = 0; i < elements.length; ++i) { var container = elements[i]; if (container._scrollTop) container.scrollTop = container._scrollTop; if (container._scrollLeft) container.scrollLeft = container._scrollLeft; } }, canHighlightLine: function() { return false; }, highlightLine: function(line) { }, doResize: function() { this._processOnResize(); }, registerRequiredCSS: function(cssFile) { this._cssFiles.push(cssFile); }, _loadCSSIfNeeded: function() { for (var i = 0; i < this._cssFiles.length; ++i) { var cssFile = this._cssFiles[i]; var viewsWithCSSFile = WebInspector.View._cssFileToVisibleViewCount[cssFile]; WebInspector.View._cssFileToVisibleViewCount[cssFile] = (viewsWithCSSFile || 0) + 1; if (!viewsWithCSSFile) this._doLoadCSS(cssFile); } }, _doLoadCSS: function(cssFile) { var styleElement = WebInspector.View._cssFileToStyleElement[cssFile]; if (styleElement) { styleElement.disabled = false; return; } if (window.debugCSS) { styleElement = document.createElement("link"); styleElement.rel = "stylesheet"; styleElement.type = "text/css"; styleElement.href = cssFile; } else { var xhr = new XMLHttpRequest(); xhr.open("GET", cssFile, false); xhr.send(null); styleElement = document.createElement("style"); styleElement.type = "text/css"; styleElement.textContent = xhr.responseText; } document.head.insertBefore(styleElement, document.head.firstChild); WebInspector.View._cssFileToStyleElement[cssFile] = styleElement; }, _disableCSSIfNeeded: function() { for (var i = 0; i < this._cssFiles.length; ++i) { var cssFile = this._cssFiles[i]; var viewsWithCSSFile = WebInspector.View._cssFileToVisibleViewCount[cssFile]; viewsWithCSSFile--; WebInspector.View._cssFileToVisibleViewCount[cssFile] = viewsWithCSSFile; if (!viewsWithCSSFile) this._doUnloadCSS(cssFile); } }, _doUnloadCSS: function(cssFile) { var styleElement = WebInspector.View._cssFileToStyleElement[cssFile]; styleElement.disabled = true; }, printViewHierarchy: function() { var lines = []; this._collectViewHierarchy("", lines); console.log(lines.join("\n")); }, _collectViewHierarchy: function(prefix, lines) { lines.push(prefix + "[" + this.element.className + "]" + (this._children.length ? " {" : "")); for (var i = 0; i < this._children.length; ++i) this._children[i]._collectViewHierarchy(prefix + " ", lines); if (this._children.length) lines.push(prefix + "}"); }, defaultFocusedElement: function() { return this._defaultFocusedElement || this.element; }, setDefaultFocusedElement: function(element) { this._defaultFocusedElement = element; }, focus: function() { var element = this.defaultFocusedElement(); if (!element || element.isAncestor(document.activeElement)) return; WebInspector.setCurrentFocusElement(element); }, measurePreferredSize: function() { this._loadCSSIfNeeded(); WebInspector.View._originalAppendChild.call(document.body, this.element); this.element.positionAt(0, 0); var result = new Size(this.element.offsetWidth, this.element.offsetHeight); this.element.positionAt(undefined, undefined); WebInspector.View._originalRemoveChild.call(document.body, this.element); this._disableCSSIfNeeded(); return result; }, __proto__: WebInspector.Object.prototype } WebInspector.View._originalAppendChild = Element.prototype.appendChild; WebInspector.View._originalInsertBefore = Element.prototype.insertBefore; WebInspector.View._originalRemoveChild = Element.prototype.removeChild; WebInspector.View._originalRemoveChildren = Element.prototype.removeChildren; WebInspector.View._incrementViewCounter = function(parentElement, childElement) { var count = (childElement.__viewCounter || 0) + (childElement.__view ? 1 : 0); if (!count) return; while (parentElement) { parentElement.__viewCounter = (parentElement.__viewCounter || 0) + count; parentElement = parentElement.parentElement; } } WebInspector.View._decrementViewCounter = function(parentElement, childElement) { var count = (childElement.__viewCounter || 0) + (childElement.__view ? 1 : 0); if (!count) return; while (parentElement) { parentElement.__viewCounter -= count; parentElement = parentElement.parentElement; } } WebInspector.View._assert = function(condition, message) { if (!condition) { console.trace(); throw new Error(message); } } Element.prototype.appendChild = function(child) { WebInspector.View._assert(!child.__view, "Attempt to add view via regular DOM operation."); return WebInspector.View._originalAppendChild.call(this, child); } Element.prototype.insertBefore = function(child, anchor) { WebInspector.View._assert(!child.__view, "Attempt to add view via regular DOM operation."); return WebInspector.View._originalInsertBefore.call(this, child, anchor); } Element.prototype.removeChild = function(child) { WebInspector.View._assert(!child.__viewCounter && !child.__view, "Attempt to remove element containing view via regular DOM operation"); return WebInspector.View._originalRemoveChild.call(this, child); } Element.prototype.removeChildren = function() { WebInspector.View._assert(!this.__viewCounter, "Attempt to remove element containing view via regular DOM operation"); WebInspector.View._originalRemoveChildren.call(this); } WebInspector.HelpScreen = function(title) { WebInspector.View.call(this); this.markAsRoot(); this.registerRequiredCSS("helpScreen.css"); this.element.className = "help-window-outer"; this.element.addEventListener("keydown", this._onKeyDown.bind(this), false); this.element.tabIndex = 0; this.element.addEventListener("focus", this._onBlur.bind(this), false); if (title) { var mainWindow = this.element.createChild("div", "help-window-main"); var captionWindow = mainWindow.createChild("div", "help-window-caption"); captionWindow.appendChild(this._createCloseButton()); this.contentElement = mainWindow.createChild("div", "help-content"); captionWindow.createChild("h1", "help-window-title").textContent = title; } } WebInspector.HelpScreen._visibleScreen = null; WebInspector.HelpScreen.prototype = { _createCloseButton: function() { var closeButton = document.createElement("button"); closeButton.className = "help-close-button"; closeButton.textContent = "\u2716"; closeButton.addEventListener("click", this.hide.bind(this), false); return closeButton; }, showModal: function() { var visibleHelpScreen = WebInspector.HelpScreen._visibleScreen; if (visibleHelpScreen === this) return; if (visibleHelpScreen) visibleHelpScreen.hide(); WebInspector.HelpScreen._visibleScreen = this; this.show(document.body); this.focus(); }, hide: function() { if (!this.isShowing()) return; WebInspector.HelpScreen._visibleScreen = null; WebInspector.restoreFocusFromElement(this.element); this.detach(); }, isClosingKey: function(keyCode) { return [ WebInspector.KeyboardShortcut.Keys.Enter.code, WebInspector.KeyboardShortcut.Keys.Esc.code, WebInspector.KeyboardShortcut.Keys.Space.code, ].indexOf(keyCode) >= 0; }, _onKeyDown: function(event) { if (this.isShowing() && this.isClosingKey(event.keyCode)) { this.hide(); event.consume(); } }, _onBlur: function(event) { if (this.isShowing() && !this.element.isSelfOrAncestor(event.target)) WebInspector.setCurrentFocusElement(this.element); }, __proto__: WebInspector.View.prototype } if (!window.InspectorFrontendHost) { WebInspector.InspectorFrontendHostStub = function() { this._attachedWindowHeight = 0; this.isStub = true; this._fileBuffers = {}; WebInspector.documentCopyEventFired = this.documentCopy.bind(this); } WebInspector.InspectorFrontendHostStub.prototype = { platform: function() { var match = navigator.userAgent.match(/Windows NT/); if (match) return "windows"; match = navigator.userAgent.match(/Mac OS X/); if (match) return "mac"; return "linux"; }, port: function() { return "unknown"; }, bringToFront: function() { this._windowVisible = true; }, closeWindow: function() { this._windowVisible = false; }, requestSetDockSide: function(side) { InspectorFrontendAPI.setDockSide(side); }, setAttachedWindowHeight: function(height) { }, moveWindowBy: function(x, y) { }, setInjectedScriptForOrigin: function(origin, script) { }, loaded: function() { }, localizedStringsURL: function() { return undefined; }, hiddenPanels: function() { return WebInspector.queryParamsObject["hiddenPanels"] || ""; }, inspectedURLChanged: function(url) { document.title = WebInspector.UIString(Preferences.applicationTitle, url); }, documentCopy: function(event) { if (!this._textToCopy) return; event.clipboardData.setData("text", this._textToCopy); event.preventDefault(); delete this._textToCopy; }, copyText: function(text) { this._textToCopy = text; if (!document.execCommand("copy")) { var screen = new WebInspector.ClipboardAccessDeniedScreen(); screen.showModal(); } }, openInNewTab: function(url) { window.open(url, "_blank"); }, canSave: function() { return true; }, save: function(url, content, forceSaveAs) { if (this._fileBuffers[url]) throw new Error("Concurrent file modification denied."); this._fileBuffers[url] = [content]; setTimeout(WebInspector.fileManager.savedURL.bind(WebInspector.fileManager, url), 0); }, append: function(url, content) { var buffer = this._fileBuffers[url]; if (!buffer) throw new Error("File is not open for write yet."); buffer.push(content); setTimeout(WebInspector.fileManager.appendedToURL.bind(WebInspector.fileManager, url), 0); }, close: function(url) { var content = this._fileBuffers[url]; delete this._fileBuffers[url]; if (!content) return; var lastSlashIndex = url.lastIndexOf("/"); var fileNameSuffix = (lastSlashIndex === -1) ? url : url.substring(lastSlashIndex + 1); var blob = new Blob(content, { type: "application/octet-stream" }); var objectUrl = window.URL.createObjectURL(blob); window.location = objectUrl + "#" + fileNameSuffix; function cleanup() { window.URL.revokeObjectURL(objectUrl); } setTimeout(cleanup, 0); }, sendMessageToBackend: function(message) { }, recordActionTaken: function(actionCode) { }, recordPanelShown: function(panelCode) { }, recordSettingChanged: function(settingCode) { }, loadResourceSynchronously: function(url) { return loadXHR(url); }, setZoomFactor: function(zoom) { }, canInspectWorkers: function() { return true; } } InspectorFrontendHost = new WebInspector.InspectorFrontendHostStub(); Preferences.localizeUI = false; WebInspector.clipboardAccessDeniedMessage = function() { return ""; } WebInspector.ClipboardAccessDeniedScreen = function() { WebInspector.HelpScreen.call(this, WebInspector.UIString("Clipboard access is denied")); var platformMessage = WebInspector.clipboardAccessDeniedMessage(); if (platformMessage) { var p = this.contentElement.createChild("p"); p.addStyleClass("help-section"); p.textContent = platformMessage; } } WebInspector.ClipboardAccessDeniedScreen.prototype = { __proto__: WebInspector.HelpScreen.prototype } } WebInspector.RemoteDebuggingTerminatedScreen = function(reason) { WebInspector.HelpScreen.call(this, WebInspector.UIString("Detached from the target")); var p = this.contentElement.createChild("p"); p.addStyleClass("help-section"); p.createChild("span").textContent = "Remote debugging has been terminated with reason: "; p.createChild("span", "error-message").textContent = reason; p.createChild("br"); p.createChild("span").textContent = "Please re-attach to the new target."; } WebInspector.RemoteDebuggingTerminatedScreen.prototype = { __proto__: WebInspector.HelpScreen.prototype } WebInspector.FileManager = function() { } WebInspector.FileManager.EventTypes = { SavedURL: "SavedURL", AppendedToURL: "AppendedToURL" } WebInspector.FileManager.prototype = { canSave: function() { return InspectorFrontendHost.canSave(); }, save: function(url, content, forceSaveAs) { var savedURLs = WebInspector.settings.savedURLs.get(); delete savedURLs[url]; WebInspector.settings.savedURLs.set(savedURLs); InspectorFrontendHost.save(url, content, forceSaveAs); }, savedURL: function(url) { var savedURLs = WebInspector.settings.savedURLs.get(); savedURLs[url] = true; WebInspector.settings.savedURLs.set(savedURLs); this.dispatchEventToListeners(WebInspector.FileManager.EventTypes.SavedURL, url); }, isURLSaved: function(url) { var savedURLs = WebInspector.settings.savedURLs.get(); return savedURLs[url]; }, append: function(url, content) { InspectorFrontendHost.append(url, content); }, close: function(url) { InspectorFrontendHost.close(url); }, appendedToURL: function(url) { this.dispatchEventToListeners(WebInspector.FileManager.EventTypes.AppendedToURL, url); }, __proto__: WebInspector.Object.prototype } WebInspector.fileManager = new WebInspector.FileManager(); WebInspector.Checkbox = function(label, className, tooltip) { this.element = document.createElement('label'); this._inputElement = document.createElement('input'); this._inputElement.type = "checkbox"; this.element.className = className; this.element.appendChild(this._inputElement); this.element.appendChild(document.createTextNode(label)); if (tooltip) this.element.title = tooltip; } WebInspector.Checkbox.prototype = { set checked(checked) { this._inputElement.checked = checked; }, get checked() { return this._inputElement.checked; }, addEventListener: function(listener) { function listenerWrapper(event) { if (listener) listener(event); event.consume(); return true; } this._inputElement.addEventListener("click", listenerWrapper, false); this.element.addEventListener("click", listenerWrapper, false); } } WebInspector.ContextMenuItem = function(topLevelMenu, type, label, disabled, checked) { this._type = type; this._label = label; this._disabled = disabled; this._checked = checked; this._contextMenu = topLevelMenu; if (type === "item" || type === "checkbox") this._id = topLevelMenu.nextId(); } WebInspector.ContextMenuItem.prototype = { id: function() { return this._id; }, type: function() { return this._type; }, _buildDescriptor: function() { switch (this._type) { case "item": return { type: "item", id: this._id, label: this._label, enabled: !this._disabled }; case "separator": return { type: "separator" }; case "checkbox": return { type: "checkbox", id: this._id, label: this._label, checked: !!this._checked, enabled: !this._disabled }; } } } WebInspector.ContextSubMenuItem = function(topLevelMenu, label, disabled) { WebInspector.ContextMenuItem.call(this, topLevelMenu, "subMenu", label, disabled); this._items = []; } WebInspector.ContextSubMenuItem.prototype = { appendItem: function(label, handler, disabled) { var item = new WebInspector.ContextMenuItem(this._contextMenu, "item", label, disabled); this._pushItem(item); this._contextMenu._setHandler(item.id(), handler); return item; }, appendSubMenuItem: function(label, disabled) { var item = new WebInspector.ContextSubMenuItem(this._contextMenu, label, disabled); this._pushItem(item); return item; }, appendCheckboxItem: function(label, handler, checked, disabled) { var item = new WebInspector.ContextMenuItem(this._contextMenu, "checkbox", label, disabled, checked); this._pushItem(item); this._contextMenu._setHandler(item.id(), handler); return item; }, appendSeparator: function() { if (this._items.length) this._pendingSeparator = true; }, _pushItem: function(item) { if (this._pendingSeparator) { this._items.push(new WebInspector.ContextMenuItem(this._contextMenu, "separator")); delete this._pendingSeparator; } this._items.push(item); }, isEmpty: function() { return !this._items.length; }, _buildDescriptor: function() { var result = { type: "subMenu", label: this._label, enabled: !this._disabled, subItems: [] }; for (var i = 0; i < this._items.length; ++i) result.subItems.push(this._items[i]._buildDescriptor()); return result; }, __proto__: WebInspector.ContextMenuItem.prototype } WebInspector.ContextMenu = function(event) { WebInspector.ContextSubMenuItem.call(this, this, ""); this._event = event; this._handlers = {}; this._id = 0; } WebInspector.ContextMenu.prototype = { nextId: function() { return this._id++; }, show: function() { var menuObject = this._buildDescriptor(); if (menuObject.length) { WebInspector._contextMenu = this; InspectorFrontendHost.showContextMenu(this._event, menuObject); } this._event.consume(); }, _setHandler: function(id, handler) { if (handler) this._handlers[id] = handler; }, _buildDescriptor: function() { var result = []; for (var i = 0; i < this._items.length; ++i) result.push(this._items[i]._buildDescriptor()); return result; }, _itemSelected: function(id) { if (this._handlers[id]) this._handlers[id].call(this); }, appendApplicableItems: function(target) { for (var i = 0; i < WebInspector.ContextMenu._providers.length; ++i) { var provider = WebInspector.ContextMenu._providers[i]; this.appendSeparator(); provider.appendApplicableItems(this._event, this, target); this.appendSeparator(); } }, __proto__: WebInspector.ContextSubMenuItem.prototype } WebInspector.ContextMenu.Provider = function() { } WebInspector.ContextMenu.Provider.prototype = { appendApplicableItems: function(event, contextMenu, target) { } } WebInspector.ContextMenu.registerProvider = function(provider) { WebInspector.ContextMenu._providers.push(provider); } WebInspector.ContextMenu._providers = []; WebInspector.contextMenuItemSelected = function(id) { if (WebInspector._contextMenu) WebInspector._contextMenu._itemSelected(id); } WebInspector.contextMenuCleared = function() { } if (!InspectorFrontendHost.showContextMenu) { WebInspector.SoftContextMenu = function(items, parentMenu) { this._items = items; this._parentMenu = parentMenu; } WebInspector.SoftContextMenu.prototype = { show: function(event) { this._x = event.x; this._y = event.y; this._time = new Date().getTime(); var absoluteX = event.pageX; var absoluteY = event.pageY; var targetElement = event.target; while (targetElement && window !== targetElement.ownerDocument.defaultView) { var frameElement = targetElement.ownerDocument.defaultView.frameElement; absoluteY += frameElement.totalOffsetTop(); absoluteX += frameElement.totalOffsetLeft(); targetElement = frameElement; } this._contextMenuElement = document.createElement("div"); this._contextMenuElement.className = "soft-context-menu"; this._contextMenuElement.tabIndex = 0; this._contextMenuElement.style.top = absoluteY + "px"; this._contextMenuElement.style.left = absoluteX + "px"; this._contextMenuElement.addEventListener("mouseup", consumeEvent, false); this._contextMenuElement.addEventListener("keydown", this._menuKeyDown.bind(this), false); for (var i = 0; i < this._items.length; ++i) this._contextMenuElement.appendChild(this._createMenuItem(this._items[i])); if (!this._parentMenu) { this._glassPaneElement = document.createElement("div"); this._glassPaneElement.className = "soft-context-menu-glass-pane"; this._glassPaneElement.tabIndex = 0; this._glassPaneElement.addEventListener("mouseup", this._glassPaneMouseUp.bind(this), false); this._glassPaneElement.appendChild(this._contextMenuElement); document.body.appendChild(this._glassPaneElement); this._focus(); } else this._parentMenu._parentGlassPaneElement().appendChild(this._contextMenuElement); if (document.body.offsetWidth < this._contextMenuElement.offsetLeft + this._contextMenuElement.offsetWidth) this._contextMenuElement.style.left = (absoluteX - this._contextMenuElement.offsetWidth) + "px"; if (document.body.offsetHeight < this._contextMenuElement.offsetTop + this._contextMenuElement.offsetHeight) this._contextMenuElement.style.top = (document.body.offsetHeight - this._contextMenuElement.offsetHeight) + "px"; event.consume(true); }, _parentGlassPaneElement: function() { if (this._glassPaneElement) return this._glassPaneElement; if (this._parentMenu) return this._parentMenu._parentGlassPaneElement(); return null; }, _createMenuItem: function(item) { if (item.type === "separator") return this._createSeparator(); if (item.type === "subMenu") return this._createSubMenu(item); var menuItemElement = document.createElement("div"); menuItemElement.className = "soft-context-menu-item"; var checkMarkElement = document.createElement("span"); checkMarkElement.textContent = "\u2713 "; checkMarkElement.className = "soft-context-menu-item-checkmark"; if (!item.checked) checkMarkElement.style.opacity = "0"; menuItemElement.appendChild(checkMarkElement); menuItemElement.appendChild(document.createTextNode(item.label)); menuItemElement.addEventListener("mousedown", this._menuItemMouseDown.bind(this), false); menuItemElement.addEventListener("mouseup", this._menuItemMouseUp.bind(this), false); menuItemElement.addEventListener("mouseover", this._menuItemMouseOver.bind(this), false); menuItemElement.addEventListener("mouseout", this._menuItemMouseOut.bind(this), false); menuItemElement._actionId = item.id; return menuItemElement; }, _createSubMenu: function(item) { var menuItemElement = document.createElement("div"); menuItemElement.className = "soft-context-menu-item"; menuItemElement._subItems = item.subItems; var checkMarkElement = document.createElement("span"); checkMarkElement.textContent = "\u2713 "; checkMarkElement.className = "soft-context-menu-item-checkmark"; checkMarkElement.style.opacity = "0"; menuItemElement.appendChild(checkMarkElement); var subMenuArrowElement = document.createElement("span"); subMenuArrowElement.textContent = "\u25B6"; subMenuArrowElement.className = "soft-context-menu-item-submenu-arrow"; menuItemElement.appendChild(document.createTextNode(item.label)); menuItemElement.appendChild(subMenuArrowElement); menuItemElement.addEventListener("mousedown", this._menuItemMouseDown.bind(this), false); menuItemElement.addEventListener("mouseup", this._menuItemMouseUp.bind(this), false); menuItemElement.addEventListener("mouseover", this._menuItemMouseOver.bind(this), false); menuItemElement.addEventListener("mouseout", this._menuItemMouseOut.bind(this), false); return menuItemElement; }, _createSeparator: function() { var separatorElement = document.createElement("div"); separatorElement.className = "soft-context-menu-separator"; separatorElement._isSeparator = true; separatorElement.addEventListener("mouseover", this._hideSubMenu.bind(this), false); separatorElement.createChild("div", "separator-line"); return separatorElement; }, _menuItemMouseDown: function(event) { event.consume(true); }, _menuItemMouseUp: function(event) { this._triggerAction(event.target, event); event.consume(); }, _focus: function() { this._contextMenuElement.focus(); }, _triggerAction: function(menuItemElement, event) { if (!menuItemElement._subItems) { this._discardMenu(true, event); if (typeof menuItemElement._actionId !== "undefined") { WebInspector.contextMenuItemSelected(menuItemElement._actionId); delete menuItemElement._actionId; } return; } this._showSubMenu(menuItemElement, event); event.consume(); }, _showSubMenu: function(menuItemElement, event) { if (menuItemElement._subMenuTimer) { clearTimeout(menuItemElement._subMenuTimer); delete menuItemElement._subMenuTimer; } if (this._subMenu) return; this._subMenu = new WebInspector.SoftContextMenu(menuItemElement._subItems, this); this._subMenu.show(this._buildMouseEventForSubMenu(menuItemElement)); }, _buildMouseEventForSubMenu: function(subMenuItemElement) { var subMenuOffset = { x: subMenuItemElement.offsetWidth - 3, y: subMenuItemElement.offsetTop - 1 }; var targetX = this._x + subMenuOffset.x; var targetY = this._y + subMenuOffset.y; var targetPageX = parseInt(this._contextMenuElement.style.left, 10) + subMenuOffset.x; var targetPageY = parseInt(this._contextMenuElement.style.top, 10) + subMenuOffset.y; return { x: targetX, y: targetY, pageX: targetPageX, pageY: targetPageY, consume: function() {} }; }, _hideSubMenu: function() { if (!this._subMenu) return; this._subMenu._discardSubMenus(); this._focus(); }, _menuItemMouseOver: function(event) { this._highlightMenuItem(event.target); }, _menuItemMouseOut: function(event) { if (!this._subMenu || !event.relatedTarget) { this._highlightMenuItem(null); return; } var relatedTarget = event.relatedTarget; if (this._contextMenuElement.isSelfOrAncestor(relatedTarget) || relatedTarget.hasStyleClass("soft-context-menu-glass-pane")) this._highlightMenuItem(null); }, _highlightMenuItem: function(menuItemElement) { if (this._highlightedMenuItemElement === menuItemElement) return; this._hideSubMenu(); if (this._highlightedMenuItemElement) { this._highlightedMenuItemElement.removeStyleClass("soft-context-menu-item-mouse-over"); if (this._highlightedMenuItemElement._subItems && this._highlightedMenuItemElement._subMenuTimer) { clearTimeout(this._highlightedMenuItemElement._subMenuTimer); delete this._highlightedMenuItemElement._subMenuTimer; } } this._highlightedMenuItemElement = menuItemElement; if (this._highlightedMenuItemElement) { this._highlightedMenuItemElement.addStyleClass("soft-context-menu-item-mouse-over"); this._contextMenuElement.focus(); if (this._highlightedMenuItemElement._subItems && !this._highlightedMenuItemElement._subMenuTimer) this._highlightedMenuItemElement._subMenuTimer = setTimeout(this._showSubMenu.bind(this, this._highlightedMenuItemElement, this._buildMouseEventForSubMenu(this._highlightedMenuItemElement)), 150); } }, _highlightPrevious: function() { var menuItemElement = this._highlightedMenuItemElement ? this._highlightedMenuItemElement.previousSibling : this._contextMenuElement.lastChild; while (menuItemElement && menuItemElement._isSeparator) menuItemElement = menuItemElement.previousSibling; if (menuItemElement) this._highlightMenuItem(menuItemElement); }, _highlightNext: function() { var menuItemElement = this._highlightedMenuItemElement ? this._highlightedMenuItemElement.nextSibling : this._contextMenuElement.firstChild; while (menuItemElement && menuItemElement._isSeparator) menuItemElement = menuItemElement.nextSibling; if (menuItemElement) this._highlightMenuItem(menuItemElement); }, _menuKeyDown: function(event) { switch (event.keyIdentifier) { case "Up": this._highlightPrevious(); break; case "Down": this._highlightNext(); break; case "Left": if (this._parentMenu) { this._highlightMenuItem(null); this._parentMenu._focus(); } break; case "Right": if (!this._highlightedMenuItemElement) break; if (this._highlightedMenuItemElement._subItems) { this._showSubMenu(this._highlightedMenuItemElement, this._buildMouseEventForSubMenu(this._highlightedMenuItemElement)); this._subMenu._focus(); this._subMenu._highlightNext(); } break; case "U+001B": this._discardMenu(true, event); break; case "Enter": if (!isEnterKey(event)) break; case "U+0020": if (this._highlightedMenuItemElement) this._triggerAction(this._highlightedMenuItemElement, event); break; } event.consume(true); }, _glassPaneMouseUp: function(event) { if (event.x === this._x && event.y === this._y && new Date().getTime() - this._time < 300) return; this._discardMenu(true, event); event.consume(); }, _discardMenu: function(closeParentMenus, event) { if (this._subMenu && !closeParentMenus) return; if (this._glassPaneElement) { var glassPane = this._glassPaneElement; delete this._glassPaneElement; document.body.removeChild(glassPane); if (this._parentMenu) { delete this._parentMenu._subMenu; if (closeParentMenus) this._parentMenu._discardMenu(closeParentMenus, event); } if (event) event.consume(true); } else if (this._parentMenu && this._contextMenuElement.parentElement) { this._discardSubMenus(); if (closeParentMenus) this._parentMenu._discardMenu(closeParentMenus, event); if (event) event.consume(true); } }, _discardSubMenus: function() { if (this._subMenu) this._subMenu._discardSubMenus(); if (this._contextMenuElement.parentElement) this._contextMenuElement.parentElement.removeChild(this._contextMenuElement); if (this._parentMenu) delete this._parentMenu._subMenu; } } InspectorFrontendHost.showContextMenu = function(event, items) { new WebInspector.SoftContextMenu(items).show(event); } } WebInspector.KeyboardShortcut = function() { } WebInspector.KeyboardShortcut.Modifiers = { None: 0, Shift: 1, Ctrl: 2, Alt: 4, Meta: 8, get CtrlOrMeta() { return WebInspector.isMac() ? this.Meta : this.Ctrl; } }; WebInspector.KeyboardShortcut.Keys = { Backspace: { code: 8, name: "\u21a4" }, Tab: { code: 9, name: { mac: "\u21e5", other: "<Tab>" } }, Enter: { code: 13, name: { mac: "\u21a9", other: "<Enter>" } }, Esc: { code: 27, name: { mac: "\u238b", other: "<Esc>" } }, Space: { code: 32, name: "<Space>" }, PageUp: { code: 33, name: { mac: "\u21de", other: "<PageUp>" } }, PageDown: { code: 34, name: { mac: "\u21df", other: "<PageDown>" } }, End: { code: 35, name: { mac: "\u2197", other: "<End>" } }, Home: { code: 36, name: { mac: "\u2196", other: "<Home>" } }, Left: { code: 37, name: "<Left>" }, Up: { code: 38, name: "<Up>" }, Right: { code: 39, name: "<Right>" }, Down: { code: 40, name: "<Down>" }, Delete: { code: 46, name: "<Del>" }, Zero: { code: 48, name: "0" }, F1: { code: 112, name: "F1" }, F2: { code: 113, name: "F2" }, F3: { code: 114, name: "F3" }, F4: { code: 115, name: "F4" }, F5: { code: 116, name: "F5" }, F6: { code: 117, name: "F6" }, F7: { code: 118, name: "F7" }, F8: { code: 119, name: "F8" }, F9: { code: 120, name: "F9" }, F10: { code: 121, name: "F10" }, F11: { code: 122, name: "F11" }, F12: { code: 123, name: "F12" }, Semicolon: { code: 186, name: ";" }, Plus: { code: 187, name: "+" }, Comma: { code: 188, name: "," }, Minus: { code: 189, name: "-" }, Period: { code: 190, name: "." }, Slash: { code: 191, name: "/" }, Apostrophe: { code: 192, name: "`" }, SingleQuote: { code: 222, name: "\'" } }; WebInspector.KeyboardShortcut.makeKey = function(keyCode, modifiers) { if (typeof keyCode === "string") keyCode = keyCode.charCodeAt(0) - 32; modifiers = modifiers || WebInspector.KeyboardShortcut.Modifiers.None; return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyCode, modifiers); } WebInspector.KeyboardShortcut.makeKeyFromEvent = function(keyboardEvent) { var modifiers = WebInspector.KeyboardShortcut.Modifiers.None; if (keyboardEvent.shiftKey) modifiers |= WebInspector.KeyboardShortcut.Modifiers.Shift; if (keyboardEvent.ctrlKey) modifiers |= WebInspector.KeyboardShortcut.Modifiers.Ctrl; if (keyboardEvent.altKey) modifiers |= WebInspector.KeyboardShortcut.Modifiers.Alt; if (keyboardEvent.metaKey) modifiers |= WebInspector.KeyboardShortcut.Modifiers.Meta; return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyboardEvent.keyCode, modifiers); } WebInspector.KeyboardShortcut.eventHasCtrlOrMeta = function(event) { return WebInspector.isMac() ? event.metaKey && !event.ctrlKey : event.ctrlKey && !event.metaKey; } WebInspector.KeyboardShortcut.makeDescriptor = function(key, modifiers) { return { key: WebInspector.KeyboardShortcut.makeKey(typeof key === "string" ? key : key.code, modifiers), name: WebInspector.KeyboardShortcut.shortcutToString(key, modifiers) }; } WebInspector.KeyboardShortcut.shortcutToString = function(key, modifiers) { return WebInspector.KeyboardShortcut._modifiersToString(modifiers) + WebInspector.KeyboardShortcut._keyName(key); } WebInspector.KeyboardShortcut._keyName = function(key) { if (typeof key === "string") return key.toUpperCase(); if (typeof key.name === "string") return key.name; return key.name[WebInspector.platform()] || key.name.other; } WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers = function(keyCode, modifiers) { return (keyCode & 255) | (modifiers << 8); }; WebInspector.KeyboardShortcut._modifiersToString = function(modifiers) { const cmdKey = "\u2318"; const optKey = "\u2325"; const shiftKey = "\u21e7"; const ctrlKey = "\u2303"; var isMac = WebInspector.isMac(); var res = ""; if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Ctrl) res += isMac ? ctrlKey : "<Ctrl> + "; if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Alt) res += isMac ? optKey : "<Alt> + "; if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Shift) res += isMac ? shiftKey : "<Shift> + "; if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Meta) res += isMac ? cmdKey : "<Win> + "; return res; }; WebInspector.KeyboardShortcut.SelectAll = WebInspector.KeyboardShortcut.makeKey("a", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta); WebInspector.TextPrompt = function(completions, stopCharacters) { this._proxyElement; this._proxyElementDisplay = "inline-block"; this._loadCompletions = completions; this._completionStopCharacters = stopCharacters || " =:[({;,!+-*/&|^<>."; this._suggestForceable = true; } WebInspector.TextPrompt.Events = { ItemApplied: "text-prompt-item-applied", ItemAccepted: "text-prompt-item-accepted" }; WebInspector.TextPrompt.prototype = { get proxyElement() { return this._proxyElement; }, setSuggestForceable: function(x) { this._suggestForceable = x; }, setSuggestBoxEnabled: function(className) { this._suggestBoxClassName = className; }, renderAsBlock: function() { this._proxyElementDisplay = "block"; }, attach: function(element) { return this._attachInternal(element); }, attachAndStartEditing: function(element, blurListener) { this._attachInternal(element); this._startEditing(blurListener); return this.proxyElement; }, _attachInternal: function(element) { if (this.proxyElement) throw "Cannot attach an attached TextPrompt"; this._element = element; this._boundOnKeyDown = this.onKeyDown.bind(this); this._boundOnMouseWheel = this.onMouseWheel.bind(this); this._boundSelectStart = this._selectStart.bind(this); this._proxyElement = element.ownerDocument.createElement("span"); this._proxyElement.style.display = this._proxyElementDisplay; element.parentElement.insertBefore(this.proxyElement, element); this.proxyElement.appendChild(element); this._element.addStyleClass("text-prompt"); this._element.addEventListener("keydown", this._boundOnKeyDown, false); this._element.addEventListener("mousewheel", this._boundOnMouseWheel, false); this._element.addEventListener("selectstart", this._boundSelectStart, false); if (typeof this._suggestBoxClassName === "string") this._suggestBox = new WebInspector.TextPrompt.SuggestBox(this, this._element, this._suggestBoxClassName); return this.proxyElement; }, detach: function() { this._removeFromElement(); this.proxyElement.parentElement.insertBefore(this._element, this.proxyElement); this.proxyElement.parentElement.removeChild(this.proxyElement); this._element.removeStyleClass("text-prompt"); this._element.removeEventListener("keydown", this._boundOnKeyDown, false); this._element.removeEventListener("mousewheel", this._boundOnMouseWheel, false); this._element.removeEventListener("selectstart", this._boundSelectStart, false); delete this._proxyElement; WebInspector.restoreFocusFromElement(this._element); }, get text() { return this._element.textContent; }, set text(x) { this._removeSuggestionAids(); if (!x) { this._element.removeChildren(); this._element.appendChild(document.createElement("br")); } else this._element.textContent = x; this.moveCaretToEndOfPrompt(); this._element.scrollIntoView(); }, _removeFromElement: function() { this.clearAutoComplete(true); this._element.removeEventListener("keydown", this._boundOnKeyDown, false); this._element.removeEventListener("selectstart", this._boundSelectStart, false); if (this._isEditing) this._stopEditing(); if (this._suggestBox) this._suggestBox.removeFromElement(); }, _startEditing: function(blurListener) { this._isEditing = true; this._element.addStyleClass("editing"); if (blurListener) { this._blurListener = blurListener; this._element.addEventListener("blur", this._blurListener, false); } this._oldTabIndex = this._element.tabIndex; if (this._element.tabIndex < 0) this._element.tabIndex = 0; WebInspector.setCurrentFocusElement(this._element); }, _stopEditing: function() { this._element.tabIndex = this._oldTabIndex; if (this._blurListener) this._element.removeEventListener("blur", this._blurListener, false); this._element.removeStyleClass("editing"); delete this._isEditing; }, _removeSuggestionAids: function() { this.clearAutoComplete(); this.hideSuggestBox(); }, _selectStart: function(event) { if (this._selectionTimeout) clearTimeout(this._selectionTimeout); this._removeSuggestionAids(); function moveBackIfOutside() { delete this._selectionTimeout; if (!this.isCaretInsidePrompt() && window.getSelection().isCollapsed) { this.moveCaretToEndOfPrompt(); this.autoCompleteSoon(); } } this._selectionTimeout = setTimeout(moveBackIfOutside.bind(this), 100); }, defaultKeyHandler: function(event, force) { this.clearAutoComplete(); this.autoCompleteSoon(force); return false; }, onMouseWheel: function(event) { }, onKeyDown: function(event) { var handled = false; var invokeDefault = true; switch (event.keyIdentifier) { case "Up": handled = this.upKeyPressed(event); break; case "Down": handled = this.downKeyPressed(event); break; case "PageUp": handled = this.pageUpKeyPressed(event); break; case "PageDown": handled = this.pageDownKeyPressed(event); break; case "U+0009": handled = this.tabKeyPressed(event); break; case "Enter": handled = this.enterKeyPressed(event); break; case "Left": case "Home": this._removeSuggestionAids(); invokeDefault = false; break; case "Right": case "End": if (this.isCaretAtEndOfPrompt()) handled = this.acceptAutoComplete(); else this._removeSuggestionAids(); invokeDefault = false; break; case "U+001B": if (this.isSuggestBoxVisible()) { this._suggestBox.hide(); handled = true; } break; case "U+0020": if (this._suggestForceable && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) { this.defaultKeyHandler(event, true); handled = true; } break; case "Alt": case "Meta": case "Shift": case "Control": invokeDefault = false; break; } if (!handled && invokeDefault) handled = this.defaultKeyHandler(event); if (handled) event.consume(true); return handled; }, acceptAutoComplete: function() { var result = false; if (this.isSuggestBoxVisible()) result = this._suggestBox.acceptSuggestion(); if (!result) result = this.acceptSuggestion(); return result; }, clearAutoComplete: function(includeTimeout) { if (includeTimeout && this._completeTimeout) { clearTimeout(this._completeTimeout); delete this._completeTimeout; } delete this._waitingForCompletions; if (!this.autoCompleteElement) return; if (this.autoCompleteElement.parentNode) this.autoCompleteElement.parentNode.removeChild(this.autoCompleteElement); delete this.autoCompleteElement; if (!this._userEnteredRange || !this._userEnteredText) return; this._userEnteredRange.deleteContents(); this._element.pruneEmptyTextNodes(); var userTextNode = document.createTextNode(this._userEnteredText); this._userEnteredRange.insertNode(userTextNode); var selectionRange = document.createRange(); selectionRange.setStart(userTextNode, this._userEnteredText.length); selectionRange.setEnd(userTextNode, this._userEnteredText.length); var selection = window.getSelection(); selection.removeAllRanges(); selection.addRange(selectionRange); delete this._userEnteredRange; delete this._userEnteredText; }, autoCompleteSoon: function(force) { var immediately = this.isSuggestBoxVisible() || force; if (!this._completeTimeout) this._completeTimeout = setTimeout(this.complete.bind(this, true, force), immediately ? 0 : 250); }, complete: function(auto, force, reverse) { this.clearAutoComplete(true); var selection = window.getSelection(); if (!selection.rangeCount) return; var selectionRange = selection.getRangeAt(0); var isEmptyInput = selectionRange.commonAncestorContainer === this._element; var shouldExit; if (auto && isEmptyInput && !force) shouldExit = true; else if (!auto && !isEmptyInput && !selectionRange.commonAncestorContainer.isDescendant(this._element)) shouldExit = true; else if (auto && !force && !this.isCaretAtEndOfPrompt() && !this.isSuggestBoxVisible()) shouldExit = true; else if (!selection.isCollapsed) shouldExit = true; else if (!force) { var wordSuffixRange = selectionRange.startContainer.rangeOfWord(selectionRange.endOffset, this._completionStopCharacters, this._element, "forward"); if (wordSuffixRange.toString().length) shouldExit = true; } if (shouldExit) { this.hideSuggestBox(); return; } var wordPrefixRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, this._completionStopCharacters, this._element, "backward"); this._waitingForCompletions = true; this._loadCompletions(this.proxyElement, wordPrefixRange, force, this._completionsReady.bind(this, selection, auto, wordPrefixRange, !!reverse)); }, _boxForAnchorAtStart: function(selection, textRange) { var rangeCopy = selection.getRangeAt(0).cloneRange(); var anchorElement = document.createElement("span"); anchorElement.textContent = "\u200B"; textRange.insertNode(anchorElement); var box = anchorElement.boxInWindow(window); anchorElement.parentElement.removeChild(anchorElement); selection.removeAllRanges(); selection.addRange(rangeCopy); return box; }, _buildCommonPrefix: function(completions, wordPrefixLength) { var commonPrefix = completions[0]; for (var i = 0; i < completions.length; ++i) { var completion = completions[i]; var lastIndex = Math.min(commonPrefix.length, completion.length); for (var j = wordPrefixLength; j < lastIndex; ++j) { if (commonPrefix[j] !== completion[j]) { commonPrefix = commonPrefix.substr(0, j); break; } } } return commonPrefix; }, _completionsReady: function(selection, auto, originalWordPrefixRange, reverse, completions, selectedIndex) { if (!this._waitingForCompletions || !completions || !completions.length) { this.hideSuggestBox(); return; } delete this._waitingForCompletions; var selectionRange = selection.getRangeAt(0); var fullWordRange = document.createRange(); fullWordRange.setStart(originalWordPrefixRange.startContainer, originalWordPrefixRange.startOffset); fullWordRange.setEnd(selectionRange.endContainer, selectionRange.endOffset); if (originalWordPrefixRange.toString() + selectionRange.toString() != fullWordRange.toString()) return; selectedIndex = selectedIndex || 0; this._userEnteredRange = fullWordRange; this._userEnteredText = fullWordRange.toString(); if (this._suggestBox) this._suggestBox.updateSuggestions(this._boxForAnchorAtStart(selection, fullWordRange), completions, selectedIndex, !this.isCaretAtEndOfPrompt()); var wordPrefixLength = originalWordPrefixRange.toString().length; if (auto) { var completionText = completions[selectedIndex]; var commonPrefix = this._buildCommonPrefix(completions, wordPrefixLength); this._commonPrefix = commonPrefix; } else { if (completions.length === 1) { var completionText = completions[selectedIndex]; wordPrefixLength = completionText.length; } else { var commonPrefix = this._buildCommonPrefix(completions, wordPrefixLength); wordPrefixLength = commonPrefix.length; if (selection.isCollapsed) var completionText = completions[selectedIndex]; else { var currentText = fullWordRange.toString(); var foundIndex = null; for (var i = 0; i < completions.length; ++i) { if (completions[i] === currentText) foundIndex = i; } var nextIndex = foundIndex + (reverse ? -1 : 1); if (foundIndex === null || nextIndex >= completions.length) var completionText = completions[selectedIndex]; else if (nextIndex < 0) var completionText = completions[completions.length - 1]; else var completionText = completions[nextIndex]; } } } if (auto) { if (this.isCaretAtEndOfPrompt()) { this._userEnteredRange.deleteContents(); this._element.pruneEmptyTextNodes(); var finalSelectionRange = document.createRange(); var prefixText = completionText.substring(0, wordPrefixLength); var suffixText = completionText.substring(wordPrefixLength); var prefixTextNode = document.createTextNode(prefixText); fullWordRange.insertNode(prefixTextNode); this.autoCompleteElement = document.createElement("span"); this.autoCompleteElement.className = "auto-complete-text"; this.autoCompleteElement.textContent = suffixText; prefixTextNode.parentNode.insertBefore(this.autoCompleteElement, prefixTextNode.nextSibling); finalSelectionRange.setStart(prefixTextNode, wordPrefixLength); finalSelectionRange.setEnd(prefixTextNode, wordPrefixLength); selection.removeAllRanges(); selection.addRange(finalSelectionRange); } } else this.applySuggestion(completionText, completions.length > 1, originalWordPrefixRange); }, _completeCommonPrefix: function() { if (!this.autoCompleteElement || !this._commonPrefix || !this._userEnteredText || !this._commonPrefix.startsWith(this._userEnteredText)) return; if (!this.isSuggestBoxVisible()) { this.acceptAutoComplete(); return; } this.autoCompleteElement.textContent = this._commonPrefix.substring(this._userEnteredText.length); this.acceptSuggestion(true) }, applySuggestion: function(completionText, isIntermediateSuggestion, originalPrefixRange) { var wordPrefixLength; if (originalPrefixRange) wordPrefixLength = originalPrefixRange.toString().length; else wordPrefixLength = this._userEnteredText ? this._userEnteredText.length : 0; this._userEnteredRange.deleteContents(); this._element.pruneEmptyTextNodes(); var finalSelectionRange = document.createRange(); var completionTextNode = document.createTextNode(completionText); this._userEnteredRange.insertNode(completionTextNode); if (this.autoCompleteElement && this.autoCompleteElement.parentNode) { this.autoCompleteElement.parentNode.removeChild(this.autoCompleteElement); delete this.autoCompleteElement; } if (isIntermediateSuggestion) finalSelectionRange.setStart(completionTextNode, wordPrefixLength); else finalSelectionRange.setStart(completionTextNode, completionText.length); finalSelectionRange.setEnd(completionTextNode, completionText.length); var selection = window.getSelection(); selection.removeAllRanges(); selection.addRange(finalSelectionRange); if (isIntermediateSuggestion) this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemApplied, { itemText: completionText }); }, acceptSuggestion: function(prefixAccepted) { if (this._isAcceptingSuggestion) return false; if (!this.autoCompleteElement || !this.autoCompleteElement.parentNode) return false; var text = this.autoCompleteElement.textContent; var textNode = document.createTextNode(text); this.autoCompleteElement.parentNode.replaceChild(textNode, this.autoCompleteElement); delete this.autoCompleteElement; var finalSelectionRange = document.createRange(); finalSelectionRange.setStart(textNode, text.length); finalSelectionRange.setEnd(textNode, text.length); var selection = window.getSelection(); selection.removeAllRanges(); selection.addRange(finalSelectionRange); if (!prefixAccepted) { this.hideSuggestBox(); this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemAccepted); } else this.autoCompleteSoon(true); return true; }, hideSuggestBox: function() { if (this.isSuggestBoxVisible()) this._suggestBox.hide(); }, isSuggestBoxVisible: function() { return this._suggestBox && this._suggestBox.visible; }, isCaretInsidePrompt: function() { return this._element.isInsertionCaretInside(); }, isCaretAtEndOfPrompt: function() { var selection = window.getSelection(); if (!selection.rangeCount || !selection.isCollapsed) return false; var selectionRange = selection.getRangeAt(0); var node = selectionRange.startContainer; if (!node.isSelfOrDescendant(this._element)) return false; if (node.nodeType === Node.TEXT_NODE && selectionRange.startOffset < node.nodeValue.length) return false; var foundNextText = false; while (node) { if (node.nodeType === Node.TEXT_NODE && node.nodeValue.length) { if (foundNextText && (!this.autoCompleteElement || !this.autoCompleteElement.isAncestor(node))) return false; foundNextText = true; } node = node.traverseNextNode(this._element); } return true; }, isCaretOnFirstLine: function() { var selection = window.getSelection(); var focusNode = selection.focusNode; if (!focusNode || focusNode.nodeType !== Node.TEXT_NODE || focusNode.parentNode !== this._element) return true; if (focusNode.textContent.substring(0, selection.focusOffset).indexOf("\n") !== -1) return false; focusNode = focusNode.previousSibling; while (focusNode) { if (focusNode.nodeType !== Node.TEXT_NODE) return true; if (focusNode.textContent.indexOf("\n") !== -1) return false; focusNode = focusNode.previousSibling; } return true; }, isCaretOnLastLine: function() { var selection = window.getSelection(); var focusNode = selection.focusNode; if (!focusNode || focusNode.nodeType !== Node.TEXT_NODE || focusNode.parentNode !== this._element) return true; if (focusNode.textContent.substring(selection.focusOffset).indexOf("\n") !== -1) return false; focusNode = focusNode.nextSibling; while (focusNode) { if (focusNode.nodeType !== Node.TEXT_NODE) return true; if (focusNode.textContent.indexOf("\n") !== -1) return false; focusNode = focusNode.nextSibling; } return true; }, moveCaretToEndOfPrompt: function() { var selection = window.getSelection(); var selectionRange = document.createRange(); var offset = this._element.childNodes.length; selectionRange.setStart(this._element, offset); selectionRange.setEnd(this._element, offset); selection.removeAllRanges(); selection.addRange(selectionRange); }, tabKeyPressed: function(event) { this._completeCommonPrefix(); return true; }, enterKeyPressed: function(event) { if (this.isSuggestBoxVisible()) return this._suggestBox.enterKeyPressed(event); return false; }, upKeyPressed: function(event) { if (this.isSuggestBoxVisible()) return this._suggestBox.upKeyPressed(event); return false; }, downKeyPressed: function(event) { if (this.isSuggestBoxVisible()) return this._suggestBox.downKeyPressed(event); return false; }, pageUpKeyPressed: function(event) { if (this.isSuggestBoxVisible()) return this._suggestBox.pageUpKeyPressed(event); return false; }, pageDownKeyPressed: function(event) { if (this.isSuggestBoxVisible()) return this._suggestBox.pageDownKeyPressed(event); return false; }, __proto__: WebInspector.Object.prototype } WebInspector.TextPromptWithHistory = function(completions, stopCharacters) { WebInspector.TextPrompt.call(this, completions, stopCharacters); this._data = []; this._historyOffset = 1; this._coalesceHistoryDupes = true; } WebInspector.TextPromptWithHistory.prototype = { get historyData() { return this._data; }, setCoalesceHistoryDupes: function(x) { this._coalesceHistoryDupes = x; }, setHistoryData: function(data) { this._data = [].concat(data); this._historyOffset = 1; }, pushHistoryItem: function(text) { if (this._uncommittedIsTop) { this._data.pop(); delete this._uncommittedIsTop; } this._historyOffset = 1; if (this._coalesceHistoryDupes && text === this._currentHistoryItem()) return; this._data.push(text); }, _pushCurrentText: function() { if (this._uncommittedIsTop) this._data.pop(); this._uncommittedIsTop = true; this.clearAutoComplete(true); this._data.push(this.text); }, _previous: function() { if (this._historyOffset > this._data.length) return undefined; if (this._historyOffset === 1) this._pushCurrentText(); ++this._historyOffset; return this._currentHistoryItem(); }, _next: function() { if (this._historyOffset === 1) return undefined; --this._historyOffset; return this._currentHistoryItem(); }, _currentHistoryItem: function() { return this._data[this._data.length - this._historyOffset]; }, defaultKeyHandler: function(event, force) { var newText; var isPrevious; switch (event.keyIdentifier) { case "Up": if (!this.isCaretOnFirstLine()) break; newText = this._previous(); isPrevious = true; break; case "Down": if (!this.isCaretOnLastLine()) break; newText = this._next(); break; case "U+0050": if (WebInspector.isMac() && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) { newText = this._previous(); isPrevious = true; } break; case "U+004E": if (WebInspector.isMac() && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) newText = this._next(); break; } if (newText !== undefined) { event.consume(true); this.text = newText; if (isPrevious) { var firstNewlineIndex = this.text.indexOf("\n"); if (firstNewlineIndex === -1) this.moveCaretToEndOfPrompt(); else { var selection = window.getSelection(); var selectionRange = document.createRange(); selectionRange.setStart(this._element.firstChild, firstNewlineIndex); selectionRange.setEnd(this._element.firstChild, firstNewlineIndex); selection.removeAllRanges(); selection.addRange(selectionRange); } } return true; } return WebInspector.TextPrompt.prototype.defaultKeyHandler.apply(this, arguments); }, __proto__: WebInspector.TextPrompt.prototype } WebInspector.TextPrompt.SuggestBox = function(textPrompt, inputElement, className) { this._textPrompt = textPrompt; this._inputElement = inputElement; this._length = 0; this._selectedIndex = -1; this._selectedElement = null; this._boundOnScroll = this._onscrollresize.bind(this, true); this._boundOnResize = this._onscrollresize.bind(this, false); window.addEventListener("scroll", this._boundOnScroll, true); window.addEventListener("resize", this._boundOnResize, true); this._bodyElement = inputElement.ownerDocument.body; this._element = inputElement.ownerDocument.createElement("div"); this._element.className = "suggest-box " + (className || ""); this._element.addEventListener("mousedown", this._onboxmousedown.bind(this), true); this.containerElement = this._element.createChild("div", "container"); this.contentElement = this.containerElement.createChild("div", "content"); } WebInspector.TextPrompt.SuggestBox.prototype = { get visible() { return !!this._element.parentElement; }, get hasSelection() { return !!this._selectedElement; }, _onscrollresize: function(isScroll, event) { if (isScroll && this._element.isAncestor(event.target) || !this.visible) return; this._updateBoxPositionWithExistingAnchor(); }, _updateBoxPositionWithExistingAnchor: function() { this._updateBoxPosition(this._anchorBox); }, _updateBoxPosition: function(anchorBox) { this.contentElement.style.display = "inline-block"; document.body.appendChild(this.contentElement); this.contentElement.positionAt(0, 0); var contentWidth = this.contentElement.offsetWidth; var contentHeight = this.contentElement.offsetHeight; this.contentElement.style.display = "block"; this.containerElement.appendChild(this.contentElement); this._anchorBox = anchorBox; const spacer = 6; const suggestBoxPaddingX = 21; var maxWidth = document.body.offsetWidth - anchorBox.x - spacer; var width = Math.min(contentWidth, maxWidth - suggestBoxPaddingX) + suggestBoxPaddingX; var paddedWidth = contentWidth + suggestBoxPaddingX; var boxX = anchorBox.x; if (width < paddedWidth) { maxWidth = document.body.offsetWidth - spacer; width = Math.min(contentWidth, maxWidth - suggestBoxPaddingX) + suggestBoxPaddingX; boxX = document.body.offsetWidth - width; } const suggestBoxPaddingY = 2; var boxY; var aboveHeight = anchorBox.y; var underHeight = document.body.offsetHeight - anchorBox.y - anchorBox.height; var maxHeight = Math.max(underHeight, aboveHeight) - spacer; var height = Math.min(contentHeight, maxHeight - suggestBoxPaddingY) + suggestBoxPaddingY; if (underHeight >= aboveHeight) { boxY = anchorBox.y + anchorBox.height; this._element.removeStyleClass("above-anchor"); this._element.addStyleClass("under-anchor"); } else { boxY = anchorBox.y - height; this._element.removeStyleClass("under-anchor"); this._element.addStyleClass("above-anchor"); } this._element.positionAt(boxX, boxY); this._element.style.width = width + "px"; this._element.style.height = height + "px"; }, _onboxmousedown: function(event) { event.preventDefault(); }, hide: function() { if (!this.visible) return; this._element.parentElement.removeChild(this._element); delete this._selectedElement; }, removeFromElement: function() { window.removeEventListener("scroll", this._boundOnScroll, true); window.removeEventListener("resize", this._boundOnResize, true); this.hide(); }, _applySuggestion: function(text, isIntermediateSuggestion) { if (!this.visible || !(text || this._selectedElement)) return false; var suggestion = text || this._selectedElement.textContent; if (!suggestion) return false; this._textPrompt.applySuggestion(suggestion, isIntermediateSuggestion); return true; }, acceptSuggestion: function(text) { var result = this._applySuggestion(text, false); this.hide(); if (!result) return false; this._textPrompt.acceptSuggestion(); return true; }, _selectClosest: function(shift, isCircular) { if (!this._length) return false; var index = this._selectedIndex + shift; if (isCircular) index = (this._length + index) % this._length; else index = Number.constrain(index, 0, this._length - 1); this._selectItem(index); this._applySuggestion(undefined, true); return true; }, updateSuggestions: function(anchorBox, completions, selectedIndex, canShowForSingleItem) { if (this._suggestTimeout) { clearTimeout(this._suggestTimeout); delete this._suggestTimeout; } this._completionsReady(anchorBox, completions, selectedIndex, canShowForSingleItem); }, _onItemMouseDown: function(text, event) { this.acceptSuggestion(text); event.consume(true); }, _createItemElement: function(prefix, text) { var element = document.createElement("div"); element.className = "suggest-box-content-item source-code"; element.tabIndex = -1; if (prefix && prefix.length && !text.indexOf(prefix)) { var prefixElement = element.createChild("span", "prefix"); prefixElement.textContent = prefix; var suffixElement = element.createChild("span", "suffix"); suffixElement.textContent = text.substring(prefix.length); } else { var suffixElement = element.createChild("span", "suffix"); suffixElement.textContent = text; } element.addEventListener("mousedown", this._onItemMouseDown.bind(this, text), false); return element; }, _updateItems: function(items, selectedIndex) { this._length = items.length; this.contentElement.removeChildren(); var userEnteredText = this._textPrompt._userEnteredText; for (var i = 0; i < items.length; ++i) { var item = items[i]; var currentItemElement = this._createItemElement(userEnteredText, item); this.contentElement.appendChild(currentItemElement); } this._selectedElement = null; if (typeof selectedIndex === "number") this._selectItem(selectedIndex); }, _selectItem: function(index) { if (this._selectedElement) this._selectedElement.classList.remove("selected"); this._selectedIndex = index; this._selectedElement = this.contentElement.children[index]; this._selectedElement.classList.add("selected"); this._selectedElement.scrollIntoViewIfNeeded(false); }, _canShowBox: function(completions, canShowForSingleItem) { if (!completions || !completions.length) return false; if (completions.length > 1) return true; return canShowForSingleItem && completions[0] !== this._textPrompt._userEnteredText; }, _rememberRowCountPerViewport: function() { if (!this.contentElement.firstChild) return; this._rowCountPerViewport = Math.floor(this.containerElement.offsetHeight / this.contentElement.firstChild.offsetHeight); }, _completionsReady: function(anchorBox, completions, selectedIndex, canShowForSingleItem) { if (this._canShowBox(completions, canShowForSingleItem)) { this._updateItems(completions, selectedIndex); this._updateBoxPosition(anchorBox); if (!this.visible) this._bodyElement.appendChild(this._element); this._rememberRowCountPerViewport(); } else this.hide(); }, upKeyPressed: function(event) { return this._selectClosest(-1, true); }, downKeyPressed: function(event) { return this._selectClosest(1, true); }, pageUpKeyPressed: function(event) { return this._selectClosest(-this._rowCountPerViewport, false); }, pageDownKeyPressed: function(event) { return this._selectClosest(this._rowCountPerViewport, false); }, enterKeyPressed: function(event) { var hasSelectedItem = !!this._selectedElement; this.acceptSuggestion(); return hasSelectedItem; }, tabKeyPressed: function(event) { return this.enterKeyPressed(event); } } WebInspector.Popover = function(popoverHelper) { WebInspector.View.call(this); this.markAsRoot(); this.element.className = "popover custom-popup-vertical-scroll custom-popup-horizontal-scroll"; this._popupArrowElement = document.createElement("div"); this._popupArrowElement.className = "arrow"; this.element.appendChild(this._popupArrowElement); this._contentDiv = document.createElement("div"); this._contentDiv.className = "content"; this.element.appendChild(this._contentDiv); this._popoverHelper = popoverHelper; } WebInspector.Popover.prototype = { show: function(element, anchor, preferredWidth, preferredHeight) { this._innerShow(null, element, anchor, preferredWidth, preferredHeight); }, showView: function(view, anchor, preferredWidth, preferredHeight) { this._innerShow(view, view.element, anchor, preferredWidth, preferredHeight); }, _innerShow: function(view, contentElement, anchor, preferredWidth, preferredHeight) { if (this._disposed) return; this.contentElement = contentElement; if (WebInspector.Popover._popover) WebInspector.Popover._popover.detach(); WebInspector.Popover._popover = this; var preferredSize = view ? view.measurePreferredSize() : this.contentElement.measurePreferredSize(); preferredWidth = preferredWidth || preferredSize.width; preferredHeight = preferredHeight || preferredSize.height; WebInspector.View.prototype.show.call(this, document.body); if (view) view.show(this._contentDiv); else this._contentDiv.appendChild(this.contentElement); this._positionElement(anchor, preferredWidth, preferredHeight); if (this._popoverHelper) { contentElement.addEventListener("mousemove", this._popoverHelper._killHidePopoverTimer.bind(this._popoverHelper), true); this.element.addEventListener("mouseout", this._popoverHelper._mouseOut.bind(this._popoverHelper), true); } }, hide: function() { this.detach(); delete WebInspector.Popover._popover; }, get disposed() { return this._disposed; }, dispose: function() { if (this.isShowing()) this.hide(); this._disposed = true; }, setCanShrink: function(canShrink) { this._hasFixedHeight = !canShrink; this._contentDiv.addStyleClass("fixed-height"); }, _positionElement: function(anchorElement, preferredWidth, preferredHeight) { const borderWidth = 25; const scrollerWidth = this._hasFixedHeight ? 0 : 11; const arrowHeight = 15; const arrowOffset = 10; const borderRadius = 10; preferredWidth = Math.max(preferredWidth, 50); const totalWidth = window.innerWidth; const totalHeight = window.innerHeight; var anchorBox = anchorElement.boxInWindow(window); var newElementPosition = { x: 0, y: 0, width: preferredWidth + scrollerWidth, height: preferredHeight }; var verticalAlignment; var roomAbove = anchorBox.y; var roomBelow = totalHeight - anchorBox.y - anchorBox.height; if (roomAbove > roomBelow) { if (anchorBox.y > newElementPosition.height + arrowHeight + borderRadius) newElementPosition.y = anchorBox.y - newElementPosition.height - arrowHeight; else { newElementPosition.y = borderRadius; newElementPosition.height = anchorBox.y - borderRadius * 2 - arrowHeight; if (this._hasFixedHeight && newElementPosition.height < preferredHeight) { newElementPosition.y = borderRadius; newElementPosition.height = preferredHeight; } } verticalAlignment = "bottom"; } else { newElementPosition.y = anchorBox.y + anchorBox.height + arrowHeight; if (newElementPosition.y + newElementPosition.height + arrowHeight - borderWidth >= totalHeight) { newElementPosition.height = totalHeight - anchorBox.y - anchorBox.height - borderRadius * 2 - arrowHeight; if (this._hasFixedHeight && newElementPosition.height < preferredHeight) { newElementPosition.y = totalHeight - preferredHeight - borderRadius; newElementPosition.height = preferredHeight; } } verticalAlignment = "top"; } var horizontalAlignment; if (anchorBox.x + newElementPosition.width < totalWidth) { newElementPosition.x = Math.max(borderRadius, anchorBox.x - borderRadius - arrowOffset); horizontalAlignment = "left"; } else if (newElementPosition.width + borderRadius * 2 < totalWidth) { newElementPosition.x = totalWidth - newElementPosition.width - borderRadius; horizontalAlignment = "right"; var arrowRightPosition = Math.max(0, totalWidth - anchorBox.x - anchorBox.width - borderRadius - arrowOffset); arrowRightPosition += anchorBox.width / 2; arrowRightPosition = Math.min(arrowRightPosition, newElementPosition.width - borderRadius - arrowOffset); this._popupArrowElement.style.right = arrowRightPosition + "px"; } else { newElementPosition.x = borderRadius; newElementPosition.width = totalWidth - borderRadius * 2; newElementPosition.height += scrollerWidth; horizontalAlignment = "left"; if (verticalAlignment === "bottom") newElementPosition.y -= scrollerWidth; this._popupArrowElement.style.left = Math.max(0, anchorBox.x - borderRadius * 2 - arrowOffset) + "px"; this._popupArrowElement.style.left += anchorBox.width / 2; } this.element.className = "popover custom-popup-vertical-scroll custom-popup-horizontal-scroll " + verticalAlignment + "-" + horizontalAlignment + "-arrow"; this.element.positionAt(newElementPosition.x - borderWidth, newElementPosition.y - borderWidth); this.element.style.width = newElementPosition.width + borderWidth * 2 + "px"; this.element.style.height = newElementPosition.height + borderWidth * 2 + "px"; }, __proto__: WebInspector.View.prototype } WebInspector.PopoverHelper = function(panelElement, getAnchor, showPopover, onHide, disableOnClick) { this._panelElement = panelElement; this._getAnchor = getAnchor; this._showPopover = showPopover; this._onHide = onHide; this._disableOnClick = !!disableOnClick; panelElement.addEventListener("mousedown", this._mouseDown.bind(this), false); panelElement.addEventListener("mousemove", this._mouseMove.bind(this), false); panelElement.addEventListener("mouseout", this._mouseOut.bind(this), false); this.setTimeout(1000); } WebInspector.PopoverHelper.prototype = { setTimeout: function(timeout) { this._timeout = timeout; }, _mouseDown: function(event) { if (this._disableOnClick || !event.target.isSelfOrDescendant(this._hoverElement)) this.hidePopover(); else { this._killHidePopoverTimer(); this._handleMouseAction(event, true); } }, _mouseMove: function(event) { if (event.target.isSelfOrDescendant(this._hoverElement)) return; this._startHidePopoverTimer(); this._handleMouseAction(event, false); }, _mouseOut: function(event) { var isPopoverMouseOut = this.isPopoverVisible() && event.relatedTarget && !event.relatedTarget.isSelfOrDescendant(this._popover._contentDiv); if (event.target === this._hoverElement || isPopoverMouseOut) this._startHidePopoverTimer(); }, _startHidePopoverTimer: function() { if (!this._popover || this._hidePopoverTimer) return; function doHide() { this._hidePopover(); delete this._hidePopoverTimer; } this._hidePopoverTimer = setTimeout(doHide.bind(this), this._timeout / 2); }, _handleMouseAction: function(event, isMouseDown) { this._resetHoverTimer(); if (event.which && this._disableOnClick) return; this._hoverElement = this._getAnchor(event.target, event); if (!this._hoverElement) return; const toolTipDelay = isMouseDown ? 0 : (this._popup ? this._timeout * 0.6 : this._timeout); this._hoverTimer = setTimeout(this._mouseHover.bind(this, this._hoverElement), toolTipDelay); }, _resetHoverTimer: function() { if (this._hoverTimer) { clearTimeout(this._hoverTimer); delete this._hoverTimer; } }, isPopoverVisible: function() { return !!this._popover; }, hidePopover: function() { this._resetHoverTimer(); this._hidePopover(); }, _hidePopover: function() { if (!this._popover) return; if (this._onHide) this._onHide(); this._popover.dispose(); delete this._popover; this._hoverElement = null; }, _mouseHover: function(element) { delete this._hoverTimer; this._hidePopover(); this._popover = new WebInspector.Popover(this); this._showPopover(element, this._popover); }, _killHidePopoverTimer: function() { if (this._hidePopoverTimer) { clearTimeout(this._hidePopoverTimer); delete this._hidePopoverTimer; this._resetHoverTimer(); } } } WebInspector.Placard = function(title, subtitle) { this.element = document.createElement("div"); this.element.className = "placard"; this.element.placard = this; this.titleElement = document.createElement("div"); this.titleElement.className = "title"; this.subtitleElement = document.createElement("div"); this.subtitleElement.className = "subtitle"; this.element.appendChild(this.subtitleElement); this.element.appendChild(this.titleElement); this.title = title; this.subtitle = subtitle; this.selected = false; } WebInspector.Placard.prototype = { get title() { return this._title; }, set title(x) { if (this._title === x) return; this._title = x; this.titleElement.textContent = x; }, get subtitle() { return this._subtitle; }, set subtitle(x) { if (this._subtitle === x) return; this._subtitle = x; this.subtitleElement.textContent = x; }, get selected() { return this._selected; }, set selected(x) { if (x) this.select(); else this.deselect(); }, select: function() { if (this._selected) return; this._selected = true; this.element.addStyleClass("selected"); }, deselect: function() { if (!this._selected) return; this._selected = false; this.element.removeStyleClass("selected"); }, toggleSelected: function() { this.selected = !this.selected; }, discard: function() { } } WebInspector.TabbedPane = function() { WebInspector.View.call(this); this.registerRequiredCSS("tabbedPane.css"); this.element.addStyleClass("tabbed-pane"); this._headerElement = this.element.createChild("div", "tabbed-pane-header"); this._headerContentsElement = this._headerElement.createChild("div", "tabbed-pane-header-contents"); this._tabsElement = this._headerContentsElement.createChild("div", "tabbed-pane-header-tabs"); this._contentElement = this.element.createChild("div", "tabbed-pane-content"); this._tabs = []; this._tabsHistory = []; this._tabsById = {}; this.element.addEventListener("click", this.focus.bind(this), false); this.element.addEventListener("mouseup", this.onMouseUp.bind(this), false); this._dropDownButton = this._createDropDownButton(); } WebInspector.TabbedPane.EventTypes = { TabSelected: "TabSelected", TabClosed: "TabClosed" } WebInspector.TabbedPane.prototype = { get visibleView() { return this._currentTab ? this._currentTab.view : null; }, get selectedTabId() { return this._currentTab ? this._currentTab.id : null; }, set shrinkableTabs(shrinkableTabs) { this._shrinkableTabs = shrinkableTabs; }, set closeableTabs(closeableTabs) { this._closeableTabs = closeableTabs; }, defaultFocusedElement: function() { return this.visibleView ? this.visibleView.defaultFocusedElement() : null; }, onMouseUp: function(event) { if (event.button === 1) event.consume(true); }, appendTab: function(id, tabTitle, view, tabTooltip, userGesture) { var tab = new WebInspector.TabbedPaneTab(this, id, tabTitle, this._closeableTabs, view, tabTooltip); this._tabsById[id] = tab; this._tabs.push(tab); this._tabsHistory.push(tab); if (this._tabsHistory[0] === tab) this.selectTab(tab.id, userGesture); this._updateTabElements(); }, closeTab: function(id, userGesture) { this._innerCloseTab(id, userGesture); this._updateTabElements(); if (this._tabsHistory.length) this.selectTab(this._tabsHistory[0].id, userGesture); }, _innerCloseTab: function(id, userGesture) { if (this._currentTab && this._currentTab.id === id) this._hideCurrentTab(); var tab = this._tabsById[id]; delete this._tabsById[id]; this._tabsHistory.splice(this._tabsHistory.indexOf(tab), 1); this._tabs.splice(this._tabs.indexOf(tab), 1); if (tab._shown) this._hideTabElement(tab); var eventData = { tabId: id, view: tab.view, isUserGesture: userGesture }; this.dispatchEventToListeners(WebInspector.TabbedPane.EventTypes.TabClosed, eventData); return true; }, closeAllTabs: function(userGesture) { var tabs = this._tabs.slice(); for (var i = 0; i < tabs.length; ++i) this._innerCloseTab(tabs[i].id, userGesture); this._updateTabElements(); }, closeOtherTabs: function(id) { var tabs = this._tabs.slice(); for (var i = 0; i < tabs.length; ++i) { if (tabs[i].id !== id) this._innerCloseTab(tabs[i].id, true); } this._updateTabElements(); this.selectTab(id, true); }, selectTab: function(id, userGesture) { var tab = this._tabsById[id]; if (!tab) return; if (this._currentTab && this._currentTab.id === id) return; this._hideCurrentTab(); this._showTab(tab); this._currentTab = tab; this._tabsHistory.splice(this._tabsHistory.indexOf(tab), 1); this._tabsHistory.splice(0, 0, tab); this._updateTabElements(); var eventData = { tabId: id, view: tab.view, isUserGesture: userGesture }; this.dispatchEventToListeners(WebInspector.TabbedPane.EventTypes.TabSelected, eventData); return true; }, lastOpenedTabIds: function(tabsCount) { function tabToTabId(tab) { return tab.id; } return this._tabsHistory.slice(0, tabsCount).map(tabToTabId); }, changeTabTitle: function(id, tabTitle) { var tab = this._tabsById[id]; tab.title = tabTitle; this._updateTabElements(); }, changeTabView: function(id, view) { var tab = this._tabsById[id]; if (this._currentTab && this._currentTab.id === tab.id) { this._hideTab(tab); tab.view = view; this._showTab(tab); } else tab.view = view; }, changeTabTooltip: function(id, tabTooltip) { var tab = this._tabsById[id]; tab.tooltip = tabTooltip; }, onResize: function() { this._updateTabElements(); }, _updateTabElements: function() { WebInspector.invokeOnceAfterBatchUpdate(this, this._innerUpdateTabElements); }, _innerUpdateTabElements: function() { if (!this.isShowing()) return; if (!this._tabs.length) this._contentElement.addStyleClass("has-no-tabs"); else this._contentElement.removeStyleClass("has-no-tabs"); if (!this._measuredDropDownButtonWidth) this._measureDropDownButton(); this._updateWidths(); this._updateTabsDropDown(); }, _showTabElement: function(index, tab) { if (index >= this._tabsElement.children.length) this._tabsElement.appendChild(tab.tabElement); else this._tabsElement.insertBefore(tab.tabElement, this._tabsElement.children[index]); tab._shown = true; }, _hideTabElement: function(tab) { this._tabsElement.removeChild(tab.tabElement); tab._shown = false; }, _createDropDownButton: function() { var dropDownContainer = document.createElement("div"); dropDownContainer.addStyleClass("tabbed-pane-header-tabs-drop-down-container"); var dropDownButton = dropDownContainer.createChild("div", "tabbed-pane-header-tabs-drop-down"); dropDownButton.appendChild(document.createTextNode("\u00bb")); this._tabsSelect = dropDownButton.createChild("select", "tabbed-pane-header-tabs-drop-down-select"); this._tabsSelect.addEventListener("change", this._tabsSelectChanged.bind(this), false); return dropDownContainer; }, _totalWidth: function() { return this._headerContentsElement.getBoundingClientRect().width; }, _updateTabsDropDown: function() { var tabsToShowIndexes = this._tabsToShowIndexes(this._tabs, this._tabsHistory, this._totalWidth(), this._measuredDropDownButtonWidth); for (var i = 0; i < this._tabs.length; ++i) { if (this._tabs[i]._shown && tabsToShowIndexes.indexOf(i) === -1) this._hideTabElement(this._tabs[i]); } for (var i = 0; i < tabsToShowIndexes.length; ++i) { var tab = this._tabs[tabsToShowIndexes[i]]; if (!tab._shown) this._showTabElement(i, tab); } this._populateDropDownFromIndex(); }, _populateDropDownFromIndex: function() { if (this._dropDownButton.parentElement) this._headerContentsElement.removeChild(this._dropDownButton); this._tabsSelect.removeChildren(); var tabsToShow = []; for (var i = 0; i < this._tabs.length; ++i) { if (!this._tabs[i]._shown) tabsToShow.push(this._tabs[i]); continue; } function compareFunction(tab1, tab2) { return tab1.title.localeCompare(tab2.title); } tabsToShow.sort(compareFunction); for (var i = 0; i < tabsToShow.length; ++i) { var option = new Option(tabsToShow[i].title); option.tab = tabsToShow[i]; this._tabsSelect.appendChild(option); } if (this._tabsSelect.options.length) { this._headerContentsElement.appendChild(this._dropDownButton); this._tabsSelect.selectedIndex = -1; } }, _tabsSelectChanged: function() { var options = this._tabsSelect.options; var selectedOption = options[this._tabsSelect.selectedIndex]; this.selectTab(selectedOption.tab.id, true); }, _measureDropDownButton: function() { this._dropDownButton.addStyleClass("measuring"); this._headerContentsElement.appendChild(this._dropDownButton); this._measuredDropDownButtonWidth = this._dropDownButton.getBoundingClientRect().width; this._headerContentsElement.removeChild(this._dropDownButton); this._dropDownButton.removeStyleClass("measuring"); }, _updateWidths: function() { var measuredWidths = this._measureWidths(); var maxWidth = this._shrinkableTabs ? this._calculateMaxWidth(measuredWidths.slice(), this._totalWidth()) : Number.MAX_VALUE; var i = 0; for (var tabId in this._tabs) { var tab = this._tabs[tabId]; tab.setWidth(Math.min(maxWidth, measuredWidths[i++])); } }, _measureWidths: function() { var measuringTabElements = []; for (var tabId in this._tabs) { var tab = this._tabs[tabId]; if (typeof tab._measuredWidth === "number") continue; var measuringTabElement = tab._createTabElement(true); measuringTabElement.__tab = tab; measuringTabElements.push(measuringTabElement); this._tabsElement.appendChild(measuringTabElement); } for (var i = 0; i < measuringTabElements.length; ++i) measuringTabElements[i].__tab._measuredWidth = measuringTabElements[i].getBoundingClientRect().width; for (var i = 0; i < measuringTabElements.length; ++i) measuringTabElements[i].parentElement.removeChild(measuringTabElements[i]); var measuredWidths = []; for (var tabId in this._tabs) measuredWidths.push(this._tabs[tabId]._measuredWidth); return measuredWidths; }, _calculateMaxWidth: function(measuredWidths, totalWidth) { if (!measuredWidths.length) return 0; measuredWidths.sort(function(x, y) { return x - y }); var totalMeasuredWidth = 0; for (var i = 0; i < measuredWidths.length; ++i) totalMeasuredWidth += measuredWidths[i]; if (totalWidth >= totalMeasuredWidth) return measuredWidths[measuredWidths.length - 1]; var totalExtraWidth = 0; for (var i = measuredWidths.length - 1; i > 0; --i) { var extraWidth = measuredWidths[i] - measuredWidths[i - 1]; totalExtraWidth += (measuredWidths.length - i) * extraWidth; if (totalWidth + totalExtraWidth >= totalMeasuredWidth) return measuredWidths[i - 1] + (totalWidth + totalExtraWidth - totalMeasuredWidth) / (measuredWidths.length - i); } return totalWidth / measuredWidths.length; }, _tabsToShowIndexes: function(tabsOrdered, tabsHistory, totalWidth, measuredDropDownButtonWidth) { var tabsToShowIndexes = []; var totalTabsWidth = 0; for (var i = 0; i < tabsHistory.length; ++i) { totalTabsWidth += tabsHistory[i].width(); var minimalRequiredWidth = totalTabsWidth; if (i !== tabsHistory.length - 1) minimalRequiredWidth += measuredDropDownButtonWidth; if (minimalRequiredWidth > totalWidth) break; tabsToShowIndexes.push(tabsOrdered.indexOf(tabsHistory[i])); } tabsToShowIndexes.sort(function(x, y) { return x - y }); return tabsToShowIndexes; }, _hideCurrentTab: function() { if (!this._currentTab) return; this._hideTab(this._currentTab); delete this._currentTab; }, _showTab: function(tab) { tab.tabElement.addStyleClass("selected"); tab.view.show(this._contentElement); }, _hideTab: function(tab) { tab.tabElement.removeStyleClass("selected"); tab.view.detach(); }, canHighlightLine: function() { return this._currentTab && this._currentTab.view && this._currentTab.view.canHighlightLine(); }, highlightLine: function(line) { if (this.canHighlightLine()) this._currentTab.view.highlightLine(line); }, elementsToRestoreScrollPositionsFor: function() { return [ this._contentElement ]; }, _insertBefore: function(tab, index) { this._tabsElement.insertBefore(tab._tabElement, this._tabsElement.childNodes[index]); var oldIndex = this._tabs.indexOf(tab); this._tabs.splice(oldIndex, 1); if (oldIndex < index) --index; this._tabs.splice(index, 0, tab); }, __proto__: WebInspector.View.prototype } WebInspector.TabbedPaneTab = function(tabbedPane, id, title, closeable, view, tooltip) { this._closeable = closeable; this._tabbedPane = tabbedPane; this._id = id; this._title = title; this._tooltip = tooltip; this._view = view; this._shown = false; this._measuredWidth; this._tabElement; } WebInspector.TabbedPaneTab.prototype = { get id() { return this._id; }, get title() { return this._title; }, set title(title) { this._title = title; if (this._titleElement) this._titleElement.textContent = title; delete this._measuredWidth; }, get view() { return this._view; }, set view(view) { this._view = view; }, get tooltip() { return this._tooltip; }, set tooltip(tooltip) { this._tooltip = tooltip; if (this._titleElement) this._titleElement.title = tooltip || ""; }, get tabElement() { if (typeof(this._tabElement) !== "undefined") return this._tabElement; this._createTabElement(false); return this._tabElement; }, width: function() { return this._width; }, setWidth: function(width) { this.tabElement.style.width = width + "px"; this._width = width; }, _createTabElement: function(measuring) { var tabElement = document.createElement("div"); tabElement.addStyleClass("tabbed-pane-header-tab"); tabElement.tabIndex = -1; var titleElement = tabElement.createChild("span", "tabbed-pane-header-tab-title"); titleElement.textContent = this.title; titleElement.title = this.tooltip || ""; if (!measuring) this._titleElement = titleElement; if (this._closeable) { var closeButtonSpan = tabElement.createChild("span", "tabbed-pane-header-tab-close-button"); closeButtonSpan.textContent = "\u00D7"; } if (measuring) tabElement.addStyleClass("measuring"); else { this._tabElement = tabElement; tabElement.addEventListener("click", this._tabClicked.bind(this), false); tabElement.addEventListener("mousedown", this._tabMouseDown.bind(this), false); if (this._closeable) { tabElement.addEventListener("contextmenu", this._tabContextMenu.bind(this), false); WebInspector.installDragHandle(tabElement, this._startTabDragging.bind(this), this._tabDragging.bind(this), this._endTabDragging.bind(this), "pointer"); } } return tabElement; }, _tabClicked: function(event) { if (this._closeable && (event.button === 1 || event.target.hasStyleClass("tabbed-pane-header-tab-close-button"))) this._tabbedPane.closeTab(this.id, true); }, _tabMouseDown: function(event) { if (event.target.hasStyleClass("tabbed-pane-header-tab-close-button") || event.button === 1) return; this._tabbedPane.selectTab(this.id, true); }, _tabContextMenu: function(event) { function close() { this._tabbedPane.closeTab(this.id, true); } function closeOthers() { this._tabbedPane.closeOtherTabs(this.id); } function closeAll() { this._tabbedPane.closeAllTabs(true); } var contextMenu = new WebInspector.ContextMenu(event); contextMenu.appendItem(WebInspector.UIString("Close"), close.bind(this)); contextMenu.appendItem(WebInspector.UIString("Close Others"), closeOthers.bind(this)); contextMenu.appendItem(WebInspector.UIString("Close All"), closeAll.bind(this)); contextMenu.show(); }, _startTabDragging: function(event) { if (event.target.hasStyleClass("tabbed-pane-header-tab-close-button")) return false; this._dragStartX = event.pageX; return true; }, _tabDragging: function(event) { var tabElements = this._tabbedPane._tabsElement.childNodes; for (var i = 0; i < tabElements.length; ++i) { var tabElement = tabElements[i]; if (tabElement === this._tabElement) continue; var intersects = tabElement.offsetLeft + tabElement.clientWidth > this._tabElement.offsetLeft && this._tabElement.offsetLeft + this._tabElement.clientWidth > tabElement.offsetLeft; if (!intersects) continue; if (Math.abs(event.pageX - this._dragStartX) < tabElement.clientWidth / 2 + 5) break; if (event.pageX - this._dragStartX > 0) { tabElement = tabElement.nextSibling; ++i; } var oldOffsetLeft = this._tabElement.offsetLeft; this._tabbedPane._insertBefore(this, i); this._dragStartX += this._tabElement.offsetLeft - oldOffsetLeft; break; } if (!this._tabElement.previousSibling && event.pageX - this._dragStartX < 0) { this._tabElement.style.setProperty("left", "0px"); return; } if (!this._tabElement.nextSibling && event.pageX - this._dragStartX > 0) { this._tabElement.style.setProperty("left", "0px"); return; } this._tabElement.style.setProperty("position", "relative"); this._tabElement.style.setProperty("left", (event.pageX - this._dragStartX) + "px"); }, _endTabDragging: function(event) { this._tabElement.style.removeProperty("position"); this._tabElement.style.removeProperty("left"); delete this._dragStartX; } } WebInspector.Drawer = function() { this.element = document.getElementById("drawer"); this._savedHeight = 200; this._mainElement = document.getElementById("main"); this._toolbarElement = document.getElementById("toolbar"); this._floatingStatusBarContainer = document.getElementById("floating-status-bar-container"); WebInspector.installDragHandle(this._floatingStatusBarContainer, this._startStatusBarDragging.bind(this), this._statusBarDragging.bind(this), this._endStatusBarDragging.bind(this), "row-resize"); this._drawerContentsElement = document.createElement("div"); this._drawerContentsElement.id = "drawer-contents"; this._drawerContentsElement.className = "drawer-contents"; this.element.appendChild(this._drawerContentsElement); this._viewStatusBar = document.createElement("div"); this._bottomStatusBar = document.getElementById("bottom-status-bar-container"); } WebInspector.Drawer.AnimationType = { Immediately: 0, Normal: 1, Slow: 2 } WebInspector.Drawer.prototype = { get visible() { return !!this._view; }, _constrainHeight: function(height) { return Number.constrain(height, Preferences.minConsoleHeight, window.innerHeight - this._mainElement.totalOffsetTop() - Preferences.minConsoleHeight); }, show: function(view, animationType) { this.immediatelyFinishAnimation(); var drawerWasVisible = this.visible; if (this._view) { this._view.detach(); this._drawerContentsElement.removeChildren(); } this._view = view; var statusBarItems = this._view.statusBarItems || []; this._viewStatusBar.removeChildren(); for (var i = 0; i < statusBarItems.length; ++i) this._viewStatusBar.appendChild(statusBarItems[i]); document.body.addStyleClass("drawer-visible"); this._floatingStatusBarContainer.insertBefore(document.getElementById("panel-status-bar"), this._floatingStatusBarContainer.firstElementChild); this._bottomStatusBar.appendChild(this._viewStatusBar); this._view.markAsRoot(); this._view.show(this._drawerContentsElement); if (drawerWasVisible) return; var height = this._constrainHeight(this._savedHeight || this.element.offsetHeight); var animations = [ {element: this.element, end: {height: height}}, {element: this._mainElement, end: {bottom: height}}, {element: this._floatingStatusBarContainer, start: {"padding-left": this._bottomStatusBar.offsetLeft}, end: {"padding-left": 0}}, {element: this._viewStatusBar, start: {opacity: 0}, end: {opacity: 1}} ]; function animationFinished() { WebInspector.inspectorView.currentPanel().doResize(); if (this._view && this._view.afterShow) this._view.afterShow(); delete this._currentAnimation; } this._currentAnimation = WebInspector.animateStyle(animations, this._animationDuration(animationType), animationFinished.bind(this)); if (animationType === WebInspector.Drawer.AnimationType.Immediately) this._currentAnimation.forceComplete(); }, hide: function(animationType) { this.immediatelyFinishAnimation(); if (!this.visible) return; this._savedHeight = this.element.offsetHeight; WebInspector.restoreFocusFromElement(this.element); document.body.removeStyleClass("drawer-visible"); WebInspector.inspectorView.currentPanel().statusBarResized(); document.body.addStyleClass("drawer-visible"); var animations = [ {element: this._mainElement, end: {bottom: 0}}, {element: this.element, end: {height: 0}}, {element: this._floatingStatusBarContainer, start: {"padding-left": 0}, end: {"padding-left": this._bottomStatusBar.offsetLeft} }, {element: this._viewStatusBar, start: {opacity: 1}, end: {opacity: 0}} ]; function animationFinished() { WebInspector.inspectorView.currentPanel().doResize(); this._view.detach(); delete this._view; this._bottomStatusBar.removeChildren(); this._bottomStatusBar.appendChild(document.getElementById("panel-status-bar")); this._drawerContentsElement.removeChildren(); document.body.removeStyleClass("drawer-visible"); delete this._currentAnimation; } this._currentAnimation = WebInspector.animateStyle(animations, this._animationDuration(animationType), animationFinished.bind(this)); if (animationType === WebInspector.Drawer.AnimationType.Immediately) this._currentAnimation.forceComplete(); }, resize: function() { if (!this.visible) return; this._view.storeScrollPositions(); var height = this._constrainHeight(parseInt(this.element.style.height, 10)); this._mainElement.style.bottom = height + "px"; this.element.style.height = height + "px"; this._view.doResize(); }, immediatelyFinishAnimation: function() { if (this._currentAnimation) this._currentAnimation.forceComplete(); }, _animationDuration: function(animationType) { switch (animationType) { case WebInspector.Drawer.AnimationType.Slow: return 2000; case WebInspector.Drawer.AnimationType.Normal: return 250; default: return 0; } }, _startStatusBarDragging: function(event) { if (!this.visible || event.target !== this._floatingStatusBarContainer) return false; this._view.storeScrollPositions(); this._statusBarDragOffset = event.pageY - this.element.totalOffsetTop(); return true; }, _statusBarDragging: function(event) { var height = window.innerHeight - event.pageY + this._statusBarDragOffset; height = Number.constrain(height, Preferences.minConsoleHeight, window.innerHeight - this._mainElement.totalOffsetTop() - Preferences.minConsoleHeight); this._mainElement.style.bottom = height + "px"; this.element.style.height = height + "px"; if (WebInspector.inspectorView.currentPanel()) WebInspector.inspectorView.currentPanel().doResize(); this._view.doResize(); event.consume(true); }, _endStatusBarDragging: function(event) { this._savedHeight = this.element.offsetHeight; delete this._statusBarDragOffset; event.consume(); } } WebInspector.drawer = null; WebInspector.ConsoleModel = function() { this.messages = []; this.warnings = 0; this.errors = 0; this._interruptRepeatCount = false; InspectorBackend.registerConsoleDispatcher(new WebInspector.ConsoleDispatcher(this)); } WebInspector.ConsoleModel.Events = { ConsoleCleared: "console-cleared", MessageAdded: "console-message-added", RepeatCountUpdated: "repeat-count-updated" } WebInspector.ConsoleModel.prototype = { enableAgent: function() { if (WebInspector.settings.monitoringXHREnabled.get()) ConsoleAgent.setMonitoringXHREnabled(true); this._enablingConsole = true; function callback() { delete this._enablingConsole; } ConsoleAgent.enable(callback.bind(this)); }, enablingConsole: function() { return !!this._enablingConsole; }, addMessage: function(msg) { this.messages.push(msg); this._previousMessage = msg; this._incrementErrorWarningCount(msg); this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.MessageAdded, msg); this._interruptRepeatCount = false; }, _incrementErrorWarningCount: function(msg) { switch (msg.level) { case WebInspector.ConsoleMessage.MessageLevel.Warning: this.warnings += msg.repeatDelta; break; case WebInspector.ConsoleMessage.MessageLevel.Error: this.errors += msg.repeatDelta; break; } }, requestClearMessages: function() { ConsoleAgent.clearMessages(); this.clearMessages(); }, clearMessages: function() { this.messages = []; this.errors = 0; this.warnings = 0; this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.ConsoleCleared); }, interruptRepeatCount: function() { this._interruptRepeatCount = true; }, _messageRepeatCountUpdated: function(count) { var msg = this._previousMessage; if (!msg) return; var prevRepeatCount = msg.totalRepeatCount; if (!this._interruptRepeatCount) { msg.repeatDelta = count - prevRepeatCount; msg.repeatCount = msg.repeatCount + msg.repeatDelta; msg.totalRepeatCount = count; msg.updateRepeatCount(); this._incrementErrorWarningCount(msg); this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.RepeatCountUpdated, msg); } else { var msgCopy = msg.clone(); msgCopy.totalRepeatCount = count; msgCopy.repeatCount = (count - prevRepeatCount) || 1; msgCopy.repeatDelta = msgCopy.repeatCount; this.addMessage(msgCopy); } }, __proto__: WebInspector.Object.prototype } WebInspector.ConsoleMessage = function(source, level, url, line, repeatCount) { this.source = source; this.level = level; this.url = url || null; this.line = line || 0; this.message = ""; repeatCount = repeatCount || 1; this.repeatCount = repeatCount; this.repeatDelta = repeatCount; this.totalRepeatCount = repeatCount; } WebInspector.ConsoleMessage.prototype = { isErrorOrWarning: function() { return (this.level === WebInspector.ConsoleMessage.MessageLevel.Warning || this.level === WebInspector.ConsoleMessage.MessageLevel.Error); }, updateRepeatCount: function() { }, clone: function() { }, location: function() { } } WebInspector.ConsoleMessage.create = function(source, level, message, type, url, line, repeatCount, parameters, stackTrace, requestId, isOutdated) { } WebInspector.ConsoleMessage.MessageSource = { HTML: "html", XML: "xml", JS: "javascript", Network: "network", ConsoleAPI: "console-api", Other: "other" } WebInspector.ConsoleMessage.MessageType = { Log: "log", Dir: "dir", DirXML: "dirxml", Trace: "trace", Clear: "clear", StartGroup: "startGroup", StartGroupCollapsed: "startGroupCollapsed", EndGroup: "endGroup", Assert: "assert", Result: "result" } WebInspector.ConsoleMessage.MessageLevel = { Tip: "tip", Log: "log", Warning: "warning", Error: "error", Debug: "debug" } WebInspector.ConsoleDispatcher = function(console) { this._console = console; } WebInspector.ConsoleDispatcher.prototype = { messageAdded: function(payload) { var consoleMessage = WebInspector.ConsoleMessage.create( payload.source, payload.level, payload.text, payload.type, payload.url, payload.line, payload.repeatCount, payload.parameters, payload.stackTrace, payload.networkRequestId, this._console._enablingConsole); this._console.addMessage(consoleMessage); }, messageRepeatCountUpdated: function(count) { this._console._messageRepeatCountUpdated(count); }, messagesCleared: function() { if (!WebInspector.settings.preserveConsoleLog.get()) this._console.clearMessages(); } } WebInspector.console = null; WebInspector.ConsoleMessageImpl = function(source, level, message, linkifier, type, url, line, repeatCount, parameters, stackTrace, requestId, isOutdated) { WebInspector.ConsoleMessage.call(this, source, level, url, line, repeatCount); this._linkifier = linkifier; this.type = type || WebInspector.ConsoleMessage.MessageType.Log; this._messageText = message; this._parameters = parameters; this._stackTrace = stackTrace; this._request = requestId ? WebInspector.networkLog.requestForId(requestId) : null; this._isOutdated = isOutdated; this._customFormatters = { "object": this._formatParameterAsObject, "array": this._formatParameterAsArray, "node": this._formatParameterAsNode, "string": this._formatParameterAsString }; } WebInspector.ConsoleMessageImpl.prototype = { _formatMessage: function() { this._formattedMessage = document.createElement("span"); this._formattedMessage.className = "console-message-text source-code"; if (this.source === WebInspector.ConsoleMessage.MessageSource.ConsoleAPI) { switch (this.type) { case WebInspector.ConsoleMessage.MessageType.Trace: this._messageElement = document.createTextNode("console.trace()"); break; case WebInspector.ConsoleMessage.MessageType.Clear: this._messageElement = document.createTextNode(WebInspector.UIString("Console was cleared")); this._formattedMessage.addStyleClass("console-info"); break; case WebInspector.ConsoleMessage.MessageType.Assert: var args = [WebInspector.UIString("Assertion failed:")]; if (this._parameters) args = args.concat(this._parameters); this._messageElement = this._format(args); break; case WebInspector.ConsoleMessage.MessageType.Dir: var obj = this._parameters ? this._parameters[0] : undefined; var args = ["%O", obj]; this._messageElement = this._format(args); break; default: var args = this._parameters || [this._messageText]; this._messageElement = this._format(args); } } else if (this.source === WebInspector.ConsoleMessage.MessageSource.Network) { if (this._request) { this._stackTrace = this._request.initiator.stackTrace; if (this._request.initiator && this._request.initiator.url) { this.url = this._request.initiator.url; this.line = this._request.initiator.lineNumber; } this._messageElement = document.createElement("span"); if (this.level === WebInspector.ConsoleMessage.MessageLevel.Error) { this._messageElement.appendChild(document.createTextNode(this._request.requestMethod + " ")); this._messageElement.appendChild(WebInspector.linkifyRequestAsNode(this._request)); if (this._request.failed) this._messageElement.appendChild(document.createTextNode(" " + this._request.localizedFailDescription)); else this._messageElement.appendChild(document.createTextNode(" " + this._request.statusCode + " (" + this._request.statusText + ")")); } else { var fragment = WebInspector.linkifyStringAsFragmentWithCustomLinkifier(this._messageText, WebInspector.linkifyRequestAsNode.bind(null, this._request, "")); this._messageElement.appendChild(fragment); } } else { if (this.url) { var isExternal = !WebInspector.resourceForURL(this.url); this._anchorElement = WebInspector.linkifyURLAsNode(this.url, this.url, "console-message-url", isExternal); } this._messageElement = this._format([this._messageText]); } } else { var args = this._parameters || [this._messageText]; this._messageElement = this._format(args); } if (this.source !== WebInspector.ConsoleMessage.MessageSource.Network || this._request) { if (this._stackTrace && this._stackTrace.length && this._stackTrace[0].url) { this._anchorElement = this._linkifyCallFrame(this._stackTrace[0]); } else if (this.url && this.url !== "undefined") { this._anchorElement = this._linkifyLocation(this.url, this.line, 0); } } this._formattedMessage.appendChild(this._messageElement); if (this._anchorElement) { this._formattedMessage.appendChild(document.createTextNode(" ")); this._formattedMessage.appendChild(this._anchorElement); } var dumpStackTrace = !!this._stackTrace && this._stackTrace.length && (this.source === WebInspector.ConsoleMessage.MessageSource.Network || this.level === WebInspector.ConsoleMessage.MessageLevel.Error || this.type === WebInspector.ConsoleMessage.MessageType.Trace); if (dumpStackTrace) { var ol = document.createElement("ol"); ol.className = "outline-disclosure"; var treeOutline = new TreeOutline(ol); var content = this._formattedMessage; var root = new TreeElement(content, null, true); content.treeElementForTest = root; treeOutline.appendChild(root); if (this.type === WebInspector.ConsoleMessage.MessageType.Trace) root.expand(); this._populateStackTraceTreeElement(root); this._formattedMessage = ol; } this._message = this._messageElement.textContent; }, get message() { var formattedMessage = this.formattedMessage; return this._message; }, get formattedMessage() { if (!this._formattedMessage) this._formatMessage(); return this._formattedMessage; }, _linkifyLocation: function(url, lineNumber, columnNumber) { lineNumber = lineNumber ? lineNumber - 1 : 0; columnNumber = columnNumber ? columnNumber - 1 : 0; return this._linkifier.linkifyLocation(url, lineNumber, columnNumber, "console-message-url"); }, _linkifyCallFrame: function(callFrame) { return this._linkifyLocation(callFrame.url, callFrame.lineNumber, callFrame.columnNumber); }, isErrorOrWarning: function() { return (this.level === WebInspector.ConsoleMessage.MessageLevel.Warning || this.level === WebInspector.ConsoleMessage.MessageLevel.Error); }, _format: function(parameters) { var formattedResult = document.createElement("span"); if (!parameters.length) return formattedResult; for (var i = 0; i < parameters.length; ++i) { if (parameters[i] instanceof WebInspector.RemoteObject) continue; if (typeof parameters[i] === "object") parameters[i] = WebInspector.RemoteObject.fromPayload(parameters[i]); else parameters[i] = WebInspector.RemoteObject.fromPrimitiveValue(parameters[i]); } var shouldFormatMessage = WebInspector.RemoteObject.type(parameters[0]) === "string" && this.type !== WebInspector.ConsoleMessage.MessageType.Result; if (shouldFormatMessage) { var result = this._formatWithSubstitutionString(parameters, formattedResult); parameters = result.unusedSubstitutions; if (parameters.length) formattedResult.appendChild(document.createTextNode(" ")); } for (var i = 0; i < parameters.length; ++i) { if (shouldFormatMessage && parameters[i].type === "string") formattedResult.appendChild(document.createTextNode(parameters[i].description)); else formattedResult.appendChild(this._formatParameter(parameters[i], false, true)); if (i < parameters.length - 1) formattedResult.appendChild(document.createTextNode(" ")); } return formattedResult; }, _formatParameter: function(output, forceObjectFormat, includePreview) { var type; if (forceObjectFormat) type = "object"; else if (output instanceof WebInspector.RemoteObject) type = output.subtype || output.type; else type = typeof output; var formatter = this._customFormatters[type]; if (!formatter) { formatter = this._formatParameterAsValue; output = output.description; } var span = document.createElement("span"); span.className = "console-formatted-" + type + " source-code"; formatter.call(this, output, span, includePreview); return span; }, _formatParameterAsValue: function(val, elem) { elem.appendChild(document.createTextNode(val)); }, _formatParameterAsObject: function(obj, elem, includePreview) { this._formatParameterAsArrayOrObject(obj, obj.description, elem, includePreview); }, _formatParameterAsArrayOrObject: function(obj, description, elem, includePreview) { var titleElement = document.createElement("span"); if (description) titleElement.createTextChild(description); if (includePreview && obj.preview) { titleElement.addStyleClass("console-object-preview"); var lossless = this._appendObjectPreview(obj, description, titleElement); if (lossless) { elem.appendChild(titleElement); return; } } var section = new WebInspector.ObjectPropertiesSection(obj, titleElement); section.enableContextMenu(); elem.appendChild(section.element); }, _appendObjectPreview: function(obj, description, titleElement) { var preview = obj.preview; var isArray = obj.subtype === "array"; if (description) titleElement.createTextChild(" "); titleElement.createTextChild(isArray ? "[" : "{"); for (var i = 0; i < preview.properties.length; ++i) { if (i > 0) titleElement.createTextChild(", "); var property = preview.properties[i]; if (!isArray || property.name != i) { titleElement.createChild("span", "name").textContent = property.name; titleElement.createTextChild(": "); } var span = titleElement.createChild("span", "console-formatted-" + property.type); if (property.type === "object") { if (property.subtype === "node") span.addStyleClass("console-formatted-preview-node"); else if (property.subtype === "regexp") span.addStyleClass("console-formatted-string"); span.textContent = property.value; } else if (property.type === "function") span.textContent = "function"; else span.textContent = property.value; } if (preview.overflow) titleElement.createChild("span").textContent = "\u2026"; titleElement.createTextChild(isArray ? "]" : "}"); return preview.lossless; }, _formatParameterAsNode: function(object, elem) { function printNode(nodeId) { if (!nodeId) { this._formatParameterAsObject(object, elem, false); return; } var treeOutline = new WebInspector.ElementsTreeOutline(false, false, true); treeOutline.setVisible(true); treeOutline.rootDOMNode = WebInspector.domAgent.nodeForId(nodeId); treeOutline.element.addStyleClass("outline-disclosure"); if (!treeOutline.children[0].hasChildren) treeOutline.element.addStyleClass("single-node"); elem.appendChild(treeOutline.element); treeOutline.element.treeElementForTest = treeOutline.children[0]; } object.pushNodeToFrontend(printNode.bind(this)); }, useArrayPreviewInFormatter: function(array) { return !!array.preview; }, _formatParameterAsArray: function(array, elem) { if (this.useArrayPreviewInFormatter(array)) { this._formatParameterAsArrayOrObject(array, "", elem, true); return; } const maxFlatArrayLength = 100; if (this._isOutdated || array.arrayLength() > maxFlatArrayLength) this._formatParameterAsObject(array, elem, false); else array.getOwnProperties(this._printArray.bind(this, array, elem)); }, _formatParameterAsString: function(output, elem) { var span = document.createElement("span"); span.className = "console-formatted-string source-code"; span.appendChild(WebInspector.linkifyStringAsFragment(output.description)); elem.removeStyleClass("console-formatted-string"); elem.appendChild(document.createTextNode("\"")); elem.appendChild(span); elem.appendChild(document.createTextNode("\"")); }, _printArray: function(array, elem, properties) { if (!properties) return; var elements = []; for (var i = 0; i < properties.length; ++i) { var property = properties[i]; var name = property.name; if (!isNaN(name)) elements[name] = this._formatAsArrayEntry(property.value); } elem.appendChild(document.createTextNode("[")); var lastNonEmptyIndex = -1; function appendUndefined(elem, index) { if (index - lastNonEmptyIndex <= 1) return; var span = elem.createChild(span, "console-formatted-undefined"); span.textContent = WebInspector.UIString("undefined × %d", index - lastNonEmptyIndex - 1); } var length = array.arrayLength(); for (var i = 0; i < length; ++i) { var element = elements[i]; if (!element) continue; if (i - lastNonEmptyIndex > 1) { appendUndefined(elem, i); elem.appendChild(document.createTextNode(", ")); } elem.appendChild(element); lastNonEmptyIndex = i; if (i < length - 1) elem.appendChild(document.createTextNode(", ")); } appendUndefined(elem, length); elem.appendChild(document.createTextNode("]")); }, _formatAsArrayEntry: function(output) { return this._formatParameter(output, output.subtype && output.subtype === "array", false); }, _formatWithSubstitutionString: function(parameters, formattedResult) { var formatters = {} function parameterFormatter(force, obj) { return this._formatParameter(obj, force, false); } function stringFormatter(obj) { return obj.description; } function floatFormatter(obj) { if (typeof obj.value !== "number") return "NaN"; return obj.value; } function integerFormatter(obj) { if (typeof obj.value !== "number") return "NaN"; return Math.floor(obj.value); } function styleFormatter(obj) { var buffer = document.createElement("span"); buffer.setAttribute("style", obj.description); for (var i = 0; i < buffer.style.length; i++) { var property = buffer.style[i]; if (isWhitelistedProperty(property)) formattedResult.style[property] = buffer.style[property]; } } function isWhitelistedProperty(property) { var prefixes = ["background", "border", "color", "font", "line", "margin", "padding", "text", "-webkit-background", "-webkit-border", "-webkit-font", "-webkit-margin", "-webkit-padding", "-webkit-text"]; for (var i = 0; i < prefixes.length; i++) { if (property.startsWith(prefixes[i])) return true; } return false; } formatters.o = parameterFormatter.bind(this, false); formatters.s = stringFormatter; formatters.f = floatFormatter; formatters.i = integerFormatter; formatters.d = integerFormatter; formatters.c = styleFormatter; formatters.O = parameterFormatter.bind(this, true); function append(a, b) { if (b instanceof Node) a.appendChild(b); else if (b) a.appendChild(WebInspector.linkifyStringAsFragment(b.toString())); return a; } return String.format(parameters[0].description, parameters.slice(1), formatters, formattedResult, append); }, clearHighlight: function() { if (!this._formattedMessage) return; var highlightedMessage = this._formattedMessage; delete this._formattedMessage; delete this._anchorElement; delete this._messageElement; this._formatMessage(); this._element.replaceChild(this._formattedMessage, highlightedMessage); }, highlightSearchResults: function(regexObject) { if (!this._formattedMessage) return; this._highlightSearchResultsInElement(regexObject, this._messageElement); if (this._anchorElement) this._highlightSearchResultsInElement(regexObject, this._anchorElement); this._element.scrollIntoViewIfNeeded(); }, _highlightSearchResultsInElement: function(regexObject, element) { regexObject.lastIndex = 0; var text = element.textContent; var match = regexObject.exec(text); var offset = 0; var matchRanges = []; while (match) { matchRanges.push({ offset: match.index, length: match[0].length }); match = regexObject.exec(text); } WebInspector.highlightSearchResults(element, matchRanges); }, matchesRegex: function(regexObject) { return regexObject.test(this._message) || (this._anchorElement && regexObject.test(this._anchorElement.textContent)); }, toMessageElement: function() { if (this._element) return this._element; var element = document.createElement("div"); element.message = this; element.className = "console-message"; this._element = element; switch (this.level) { case WebInspector.ConsoleMessage.MessageLevel.Tip: element.addStyleClass("console-tip-level"); break; case WebInspector.ConsoleMessage.MessageLevel.Log: element.addStyleClass("console-log-level"); break; case WebInspector.ConsoleMessage.MessageLevel.Debug: element.addStyleClass("console-debug-level"); break; case WebInspector.ConsoleMessage.MessageLevel.Warning: element.addStyleClass("console-warning-level"); break; case WebInspector.ConsoleMessage.MessageLevel.Error: element.addStyleClass("console-error-level"); break; } if (this.type === WebInspector.ConsoleMessage.MessageType.StartGroup || this.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed) element.addStyleClass("console-group-title"); element.appendChild(this.formattedMessage); if (this.repeatCount > 1) this.updateRepeatCount(); return element; }, _populateStackTraceTreeElement: function(parentTreeElement) { for (var i = 0; i < this._stackTrace.length; i++) { var frame = this._stackTrace[i]; var content = document.createElement("div"); var messageTextElement = document.createElement("span"); messageTextElement.className = "console-message-text source-code"; var functionName = frame.functionName || WebInspector.UIString("(anonymous function)"); messageTextElement.appendChild(document.createTextNode(functionName)); content.appendChild(messageTextElement); if (frame.url) { content.appendChild(document.createTextNode(" ")); var urlElement = this._linkifyCallFrame(frame); content.appendChild(urlElement); } var treeElement = new TreeElement(content); parentTreeElement.appendChild(treeElement); } }, updateRepeatCount: function() { if (!this.repeatCountElement) { this.repeatCountElement = document.createElement("span"); this.repeatCountElement.className = "bubble"; this._element.insertBefore(this.repeatCountElement, this._element.firstChild); this._element.addStyleClass("repeated-message"); } this.repeatCountElement.textContent = this.repeatCount; }, toString: function() { var sourceString; switch (this.source) { case WebInspector.ConsoleMessage.MessageSource.HTML: sourceString = "HTML"; break; case WebInspector.ConsoleMessage.MessageSource.XML: sourceString = "XML"; break; case WebInspector.ConsoleMessage.MessageSource.JS: sourceString = "JS"; break; case WebInspector.ConsoleMessage.MessageSource.Network: sourceString = "Network"; break; case WebInspector.ConsoleMessage.MessageSource.ConsoleAPI: sourceString = "ConsoleAPI"; break; case WebInspector.ConsoleMessage.MessageSource.Other: sourceString = "Other"; break; } var typeString; switch (this.type) { case WebInspector.ConsoleMessage.MessageType.Log: typeString = "Log"; break; case WebInspector.ConsoleMessage.MessageType.Dir: typeString = "Dir"; break; case WebInspector.ConsoleMessage.MessageType.DirXML: typeString = "Dir XML"; break; case WebInspector.ConsoleMessage.MessageType.Trace: typeString = "Trace"; break; case WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed: case WebInspector.ConsoleMessage.MessageType.StartGroup: typeString = "Start Group"; break; case WebInspector.ConsoleMessage.MessageType.EndGroup: typeString = "End Group"; break; case WebInspector.ConsoleMessage.MessageType.Assert: typeString = "Assert"; break; case WebInspector.ConsoleMessage.MessageType.Result: typeString = "Result"; break; } var levelString; switch (this.level) { case WebInspector.ConsoleMessage.MessageLevel.Tip: levelString = "Tip"; break; case WebInspector.ConsoleMessage.MessageLevel.Log: levelString = "Log"; break; case WebInspector.ConsoleMessage.MessageLevel.Warning: levelString = "Warning"; break; case WebInspector.ConsoleMessage.MessageLevel.Debug: levelString = "Debug"; break; case WebInspector.ConsoleMessage.MessageLevel.Error: levelString = "Error"; break; } return sourceString + " " + typeString + " " + levelString + ": " + this.formattedMessage.textContent + "\n" + this.url + " line " + this.line; }, get text() { return this._messageText; }, location: function() { var lineNumber = this.stackTrace ? this.stackTrace[0].lineNumber - 1 : this.line - 1; var columnNumber = this.stackTrace && this.stackTrace[0].columnNumber ? this.stackTrace[0].columnNumber - 1 : 0; return WebInspector.debuggerModel.createRawLocationByURL(this.url, lineNumber, columnNumber); }, isEqual: function(msg) { if (!msg) return false; if (this._stackTrace) { if (!msg._stackTrace) return false; var l = this._stackTrace; var r = msg._stackTrace; if (l.length !== r.length) return false; for (var i = 0; i < l.length; i++) { if (l[i].url !== r[i].url || l[i].functionName !== r[i].functionName || l[i].lineNumber !== r[i].lineNumber || l[i].columnNumber !== r[i].columnNumber) return false; } } return (this.source === msg.source) && (this.type === msg.type) && (this.level === msg.level) && (this.line === msg.line) && (this.url === msg.url) && (this.message === msg.message) && (this._request === msg._request); }, get stackTrace() { return this._stackTrace; }, clone: function() { return WebInspector.ConsoleMessage.create(this.source, this.level, this._messageText, this.type, this.url, this.line, this.repeatCount, this._parameters, this._stackTrace, this._request ? this._request.requestId : undefined, this._isOutdated); }, __proto__: WebInspector.ConsoleMessage.prototype } WebInspector.ConsoleView = function(hideContextSelector) { WebInspector.View.call(this); this.element.id = "console-view"; this.messages = []; this._clearConsoleButton = new WebInspector.StatusBarButton(WebInspector.UIString("Clear console log."), "clear-status-bar-item"); this._clearConsoleButton.addEventListener("click", this._requestClearMessages, this); this._frameSelector = new WebInspector.StatusBarComboBox(this._frameChanged.bind(this), "console-context"); this._contextSelector = new WebInspector.StatusBarComboBox(this._contextChanged.bind(this), "console-context"); if (hideContextSelector) { this._frameSelector.element.addStyleClass("hidden"); this._contextSelector.element.addStyleClass("hidden"); } this.messagesElement = document.createElement("div"); this.messagesElement.id = "console-messages"; this.messagesElement.className = "monospace"; this.messagesElement.addEventListener("click", this._messagesClicked.bind(this), true); this.element.appendChild(this.messagesElement); this._scrolledToBottom = true; this.promptElement = document.createElement("div"); this.promptElement.id = "console-prompt"; this.promptElement.className = "source-code"; this.promptElement.spellcheck = false; this.messagesElement.appendChild(this.promptElement); this.messagesElement.appendChild(document.createElement("br")); this.topGroup = new WebInspector.ConsoleGroup(null); this.messagesElement.insertBefore(this.topGroup.element, this.promptElement); this.currentGroup = this.topGroup; this._filterBarElement = document.createElement("div"); this._filterBarElement.className = "scope-bar status-bar-item"; function createDividerElement() { var dividerElement = document.createElement("div"); dividerElement.addStyleClass("scope-bar-divider"); this._filterBarElement.appendChild(dividerElement); } var updateFilterHandler = this._updateFilter.bind(this); function createFilterElement(category, label) { var categoryElement = document.createElement("li"); categoryElement.category = category; categoryElement.className = category; categoryElement.addEventListener("click", updateFilterHandler, false); categoryElement.textContent = label; this._filterBarElement.appendChild(categoryElement); return categoryElement; } this.allElement = createFilterElement.call(this, "all", WebInspector.UIString("All")); createDividerElement.call(this); this.errorElement = createFilterElement.call(this, "errors", WebInspector.UIString("Errors")); this.warningElement = createFilterElement.call(this, "warnings", WebInspector.UIString("Warnings")); this.logElement = createFilterElement.call(this, "logs", WebInspector.UIString("Logs")); this.filter(this.allElement, false); this._registerShortcuts(); this.registerRequiredCSS("textPrompt.css"); this.messagesElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), false); WebInspector.settings.monitoringXHREnabled.addChangeListener(this._monitoringXHREnabledSettingChanged.bind(this)); WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._consoleMessageAdded, this); WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this); this._linkifier = new WebInspector.Linkifier(); this.prompt = new WebInspector.TextPromptWithHistory(WebInspector.runtimeModel.completionsForTextPrompt.bind(WebInspector.runtimeModel)); this.prompt.setSuggestBoxEnabled("generic-suggest"); this.prompt.renderAsBlock(); this.prompt.attach(this.promptElement); this.prompt.proxyElement.addEventListener("keydown", this._promptKeyDown.bind(this), false); this.prompt.setHistoryData(WebInspector.settings.consoleHistory.get()); WebInspector.runtimeModel.contextLists().forEach(this._addFrame, this); WebInspector.runtimeModel.addEventListener(WebInspector.RuntimeModel.Events.FrameExecutionContextListAdded, this._frameAdded, this); WebInspector.runtimeModel.addEventListener(WebInspector.RuntimeModel.Events.FrameExecutionContextListRemoved, this._frameRemoved, this); } WebInspector.ConsoleView.Events = { ConsoleCleared: "console-cleared", EntryAdded: "console-entry-added", } WebInspector.ConsoleView.prototype = { get statusBarItems() { return [this._clearConsoleButton.element, this._frameSelector.element, this._contextSelector.element, this._filterBarElement]; }, _frameAdded: function(event) { var contextList = (event.data); this._addFrame(contextList); }, _addFrame: function(contextList) { var option = document.createElement("option"); option.text = contextList.displayName; option.title = contextList.url; option._contextList = contextList; contextList._consoleOption = option; this._frameSelector.addOption(option); contextList.addEventListener(WebInspector.FrameExecutionContextList.EventTypes.ContextsUpdated, this._frameUpdated, this); contextList.addEventListener(WebInspector.FrameExecutionContextList.EventTypes.ContextAdded, this._contextAdded, this); this._frameChanged(); }, _frameRemoved: function(event) { var contextList = (event.data); this._frameSelector.removeOption(contextList._consoleOption); this._frameChanged(); }, _frameChanged: function() { var context = this._currentFrame(); if (!context) { WebInspector.runtimeModel.setCurrentExecutionContext(null); this._contextSelector.element.addStyleClass("hidden"); return; } var executionContexts = context.executionContexts(); if (executionContexts.length) WebInspector.runtimeModel.setCurrentExecutionContext(executionContexts[0]); if (executionContexts.length === 1) { this._contextSelector.element.addStyleClass("hidden"); return; } this._contextSelector.element.removeStyleClass("hidden"); this._contextSelector.removeOptions(); for (var i = 0; i < executionContexts.length; i++) this._appendContextOption(executionContexts[i]); }, _appendContextOption: function(executionContext) { if (!WebInspector.runtimeModel.currentExecutionContext()) WebInspector.runtimeModel.setCurrentExecutionContext(executionContext); var option = document.createElement("option"); option.text = executionContext.name; option.title = executionContext.id; option._executionContext = executionContext; this._contextSelector.addOption(option); }, _contextChanged: function(event) { var option = this._contextSelector.selectedOption(); WebInspector.runtimeModel.setCurrentExecutionContext(option ? option._executionContext : null); }, _frameUpdated: function(event) { var contextList = event.data; var option = contextList._consoleOption; option.text = contextList.displayName; option.title = contextList.url; }, _contextAdded: function(event) { var contextList = event.data; if (contextList === this._currentFrame()) this._frameChanged(); }, _currentFrame: function() { var option = this._frameSelector.selectedOption(); return option ? option._contextList : undefined; }, _updateFilter: function(e) { var isMac = WebInspector.isMac(); var selectMultiple = false; if (isMac && e.metaKey && !e.ctrlKey && !e.altKey && !e.shiftKey) selectMultiple = true; if (!isMac && e.ctrlKey && !e.metaKey && !e.altKey && !e.shiftKey) selectMultiple = true; this.filter(e.target, selectMultiple); }, filter: function(target, selectMultiple) { function unselectAll() { this.allElement.removeStyleClass("selected"); this.errorElement.removeStyleClass("selected"); this.warningElement.removeStyleClass("selected"); this.logElement.removeStyleClass("selected"); this.messagesElement.removeStyleClass("filter-all"); this.messagesElement.removeStyleClass("filter-errors"); this.messagesElement.removeStyleClass("filter-warnings"); this.messagesElement.removeStyleClass("filter-logs"); } var targetFilterClass = "filter-" + target.category; if (target.category === "all") { if (target.hasStyleClass("selected")) { return; } unselectAll.call(this); } else { if (this.allElement.hasStyleClass("selected")) { this.allElement.removeStyleClass("selected"); this.messagesElement.removeStyleClass("filter-all"); } } if (!selectMultiple) { unselectAll.call(this); target.addStyleClass("selected"); this.messagesElement.addStyleClass(targetFilterClass); return; } if (target.hasStyleClass("selected")) { target.removeStyleClass("selected"); this.messagesElement.removeStyleClass(targetFilterClass); } else { target.addStyleClass("selected"); this.messagesElement.addStyleClass(targetFilterClass); } }, willHide: function() { this.prompt.hideSuggestBox(); this.prompt.clearAutoComplete(true); }, wasShown: function() { if (!this.prompt.isCaretInsidePrompt()) this.prompt.moveCaretToEndOfPrompt(); }, afterShow: function() { WebInspector.setCurrentFocusElement(this.promptElement); }, storeScrollPositions: function() { WebInspector.View.prototype.storeScrollPositions.call(this); this._scrolledToBottom = this.messagesElement.isScrolledToBottom(); }, restoreScrollPositions: function() { if (this._scrolledToBottom) this._immediatelyScrollIntoView(); else WebInspector.View.prototype.restoreScrollPositions.call(this); }, onResize: function() { this.restoreScrollPositions(); }, _isScrollIntoViewScheduled: function() { return !!this._scrollIntoViewTimer; }, _scheduleScrollIntoView: function() { if (this._scrollIntoViewTimer) return; function scrollIntoView() { delete this._scrollIntoViewTimer; this.promptElement.scrollIntoView(true); } this._scrollIntoViewTimer = setTimeout(scrollIntoView.bind(this), 20); }, _immediatelyScrollIntoView: function() { this.promptElement.scrollIntoView(true); this._cancelScheduledScrollIntoView(); }, _cancelScheduledScrollIntoView: function() { if (!this._isScrollIntoViewScheduled()) return; clearTimeout(this._scrollIntoViewTimer); delete this._scrollIntoViewTimer; }, _consoleMessageAdded: function(event) { this._appendConsoleMessage(event.data); }, _appendConsoleMessage: function(msg) { if (!this._isScrollIntoViewScheduled() && ((msg instanceof WebInspector.ConsoleCommandResult) || this.messagesElement.isScrolledToBottom())) this._scheduleScrollIntoView(); this.messages.push(msg); if (msg.type === WebInspector.ConsoleMessage.MessageType.EndGroup) { var parentGroup = this.currentGroup.parentGroup if (parentGroup) this.currentGroup = parentGroup; } else { if (msg.type === WebInspector.ConsoleMessage.MessageType.StartGroup || msg.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed) { var group = new WebInspector.ConsoleGroup(this.currentGroup); this.currentGroup.messagesElement.appendChild(group.element); this.currentGroup = group; } this.currentGroup.addMessage(msg); } this.dispatchEventToListeners(WebInspector.ConsoleView.Events.EntryAdded, msg); }, _consoleCleared: function() { this._scrolledToBottom = true; this.messages = []; this.currentGroup = this.topGroup; this.topGroup.messagesElement.removeChildren(); this.dispatchEventToListeners(WebInspector.ConsoleView.Events.ConsoleCleared); this._linkifier.reset(); }, _handleContextMenuEvent: function(event) { if (!window.getSelection().isCollapsed) { return; } if (event.target.enclosingNodeOrSelfWithNodeName("a")) return; var contextMenu = new WebInspector.ContextMenu(event); function monitoringXHRItemAction() { WebInspector.settings.monitoringXHREnabled.set(!WebInspector.settings.monitoringXHREnabled.get()); } contextMenu.appendCheckboxItem(WebInspector.UIString("Log XMLHttpRequests"), monitoringXHRItemAction.bind(this), WebInspector.settings.monitoringXHREnabled.get()); function preserveLogItemAction() { WebInspector.settings.preserveConsoleLog.set(!WebInspector.settings.preserveConsoleLog.get()); } contextMenu.appendCheckboxItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Preserve log upon navigation" : "Preserve Log upon Navigation"), preserveLogItemAction.bind(this), WebInspector.settings.preserveConsoleLog.get()); contextMenu.appendSeparator(); contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Clear console" : "Clear Console"), this._requestClearMessages.bind(this)); contextMenu.show(); }, _monitoringXHREnabledSettingChanged: function(event) { ConsoleAgent.setMonitoringXHREnabled(event.data); }, _messagesClicked: function(event) { if (!this.prompt.isCaretInsidePrompt() && window.getSelection().isCollapsed) this.prompt.moveCaretToEndOfPrompt(); }, _registerShortcuts: function() { this._shortcuts = {}; var shortcut = WebInspector.KeyboardShortcut; if (WebInspector.isMac()) { var shortcutK = shortcut.makeDescriptor("k", WebInspector.KeyboardShortcut.Modifiers.Meta); this._shortcuts[shortcutK.key] = this._requestClearMessages.bind(this); } var shortcutL = shortcut.makeDescriptor("l", WebInspector.KeyboardShortcut.Modifiers.Ctrl); this._shortcuts[shortcutL.key] = this._requestClearMessages.bind(this); var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("Console")); var keys = WebInspector.isMac() ? [ shortcutK.name, shortcutL.name ] : [ shortcutL.name ]; section.addAlternateKeys(keys, WebInspector.UIString("Clear console")); keys = [ shortcut.shortcutToString(shortcut.Keys.Tab), shortcut.shortcutToString(shortcut.Keys.Tab, shortcut.Modifiers.Shift) ]; section.addRelatedKeys(keys, WebInspector.UIString("Next/previous suggestion")); section.addKey(shortcut.shortcutToString(shortcut.Keys.Right), WebInspector.UIString("Accept suggestion")); keys = [ shortcut.shortcutToString(shortcut.Keys.Down), shortcut.shortcutToString(shortcut.Keys.Up) ]; section.addRelatedKeys(keys, WebInspector.UIString("Next/previous line")); keys = [ shortcut.shortcutToString("N", shortcut.Modifiers.Alt), shortcut.shortcutToString("P", shortcut.Modifiers.Alt) ]; if (WebInspector.isMac()) section.addRelatedKeys(keys, WebInspector.UIString("Next/previous command")); section.addKey(shortcut.shortcutToString(shortcut.Keys.Enter), WebInspector.UIString("Execute command")); }, _requestClearMessages: function() { WebInspector.console.requestClearMessages(); }, _promptKeyDown: function(event) { if (isEnterKey(event)) { this._enterKeyPressed(event); return; } var shortcut = WebInspector.KeyboardShortcut.makeKeyFromEvent(event); var handler = this._shortcuts[shortcut]; if (handler) { handler(); event.preventDefault(); return; } }, evaluateUsingTextPrompt: function(expression, showResultOnly) { this._appendCommand(expression, this.prompt.text, false, showResultOnly); }, _enterKeyPressed: function(event) { if (event.altKey || event.ctrlKey || event.shiftKey) return; event.consume(true); this.prompt.clearAutoComplete(true); var str = this.prompt.text; if (!str.length) return; this._appendCommand(str, "", true, false); }, _printResult: function(result, wasThrown, originatingCommand) { if (!result) return; this._appendConsoleMessage(new WebInspector.ConsoleCommandResult(result, wasThrown, originatingCommand, this._linkifier)); }, _appendCommand: function(text, newPromptText, useCommandLineAPI, showResultOnly) { if (!showResultOnly) { var commandMessage = new WebInspector.ConsoleCommand(text); WebInspector.console.interruptRepeatCount(); this._appendConsoleMessage(commandMessage); } this.prompt.text = newPromptText; function printResult(result, wasThrown) { if (!result) return; if (!showResultOnly) { this.prompt.pushHistoryItem(text); WebInspector.settings.consoleHistory.set(this.prompt.historyData.slice(-30)); } this._printResult(result, wasThrown, commandMessage); } WebInspector.runtimeModel.evaluate(text, "console", useCommandLineAPI, false, false, true, printResult.bind(this)); WebInspector.userMetrics.ConsoleEvaluated.record(); }, elementsToRestoreScrollPositionsFor: function() { return [this.messagesElement]; }, __proto__: WebInspector.View.prototype } WebInspector.ConsoleCommand = function(command) { this.command = command; } WebInspector.ConsoleCommand.prototype = { clearHighlight: function() { var highlightedMessage = this._formattedCommand; delete this._formattedCommand; this._formatCommand(); this._element.replaceChild(this._formattedCommand, highlightedMessage); }, highlightSearchResults: function(regexObject) { regexObject.lastIndex = 0; var text = this.command; var match = regexObject.exec(text); var offset = 0; var matchRanges = []; while (match) { matchRanges.push({ offset: match.index, length: match[0].length }); match = regexObject.exec(text); } WebInspector.highlightSearchResults(this._formattedCommand, matchRanges); this._element.scrollIntoViewIfNeeded(); }, matchesRegex: function(regexObject) { return regexObject.test(this.command); }, toMessageElement: function() { if (!this._element) { this._element = document.createElement("div"); this._element.command = this; this._element.className = "console-user-command"; this._formatCommand(); this._element.appendChild(this._formattedCommand); } return this._element; }, _formatCommand: function() { this._formattedCommand = document.createElement("span"); this._formattedCommand.className = "console-message-text source-code"; this._formattedCommand.textContent = this.command; }, } WebInspector.ConsoleCommandResult = function(result, wasThrown, originatingCommand, linkifier) { var level = (wasThrown ? WebInspector.ConsoleMessage.MessageLevel.Error : WebInspector.ConsoleMessage.MessageLevel.Log); this.originatingCommand = originatingCommand; WebInspector.ConsoleMessageImpl.call(this, WebInspector.ConsoleMessage.MessageSource.JS, level, "", linkifier, WebInspector.ConsoleMessage.MessageType.Result, undefined, undefined, undefined, [result]); } WebInspector.ConsoleCommandResult.prototype = { useArrayPreviewInFormatter: function(array) { return false; }, toMessageElement: function() { var element = WebInspector.ConsoleMessageImpl.prototype.toMessageElement.call(this); element.addStyleClass("console-user-command-result"); return element; }, __proto__: WebInspector.ConsoleMessageImpl.prototype } WebInspector.ConsoleGroup = function(parentGroup) { this.parentGroup = parentGroup; var element = document.createElement("div"); element.className = "console-group"; element.group = this; this.element = element; if (parentGroup) { var bracketElement = document.createElement("div"); bracketElement.className = "console-group-bracket"; element.appendChild(bracketElement); } var messagesElement = document.createElement("div"); messagesElement.className = "console-group-messages"; element.appendChild(messagesElement); this.messagesElement = messagesElement; } WebInspector.ConsoleGroup.prototype = { addMessage: function(msg) { var element = msg.toMessageElement(); if (msg.type === WebInspector.ConsoleMessage.MessageType.StartGroup || msg.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed) { this.messagesElement.parentNode.insertBefore(element, this.messagesElement); element.addEventListener("click", this._titleClicked.bind(this), false); var groupElement = element.enclosingNodeOrSelfWithClass("console-group"); if (groupElement && msg.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed) groupElement.addStyleClass("collapsed"); } else this.messagesElement.appendChild(element); if (element.previousSibling && msg.originatingCommand && element.previousSibling.command === msg.originatingCommand) element.previousSibling.addStyleClass("console-adjacent-user-command-result"); }, _titleClicked: function(event) { var groupTitleElement = event.target.enclosingNodeOrSelfWithClass("console-group-title"); if (groupTitleElement) { var groupElement = groupTitleElement.enclosingNodeOrSelfWithClass("console-group"); if (groupElement) if (groupElement.hasStyleClass("collapsed")) groupElement.removeStyleClass("collapsed"); else groupElement.addStyleClass("collapsed"); groupTitleElement.scrollIntoViewIfNeeded(true); } event.consume(true); } } WebInspector.consoleView = null; WebInspector.ConsoleMessage.create = function(source, level, message, type, url, line, repeatCount, parameters, stackTrace, requestId, isOutdated) { return new WebInspector.ConsoleMessageImpl(source, level, message, WebInspector.consoleView._linkifier, type, url, line, repeatCount, parameters, stackTrace, requestId, isOutdated); } WebInspector.Panel = function(name) { WebInspector.View.call(this); WebInspector.panels[name] = this; this.element.addStyleClass("panel"); this.element.addStyleClass(name); this._panelName = name; this._shortcuts = {}; WebInspector.settings[this._sidebarWidthSettingName()] = WebInspector.settings.createSetting(this._sidebarWidthSettingName(), undefined); } WebInspector.Panel.counterRightMargin = 25; WebInspector.Panel.prototype = { get name() { return this._panelName; }, show: function() { WebInspector.View.prototype.show.call(this, WebInspector.inspectorView.panelsElement()); }, wasShown: function() { var statusBarItems = this.statusBarItems; if (statusBarItems) { this._statusBarItemContainer = document.createElement("div"); for (var i = 0; i < statusBarItems.length; ++i) this._statusBarItemContainer.appendChild(statusBarItems[i]); document.getElementById("panel-status-bar").appendChild(this._statusBarItemContainer); } this.focus(); }, willHide: function() { if (this._statusBarItemContainer && this._statusBarItemContainer.parentNode) this._statusBarItemContainer.parentNode.removeChild(this._statusBarItemContainer); delete this._statusBarItemContainer; }, reset: function() { this.searchCanceled(); }, defaultFocusedElement: function() { return this.sidebarTreeElement || this.element; }, searchCanceled: function() { WebInspector.searchController.updateSearchMatchesCount(0, this); }, performSearch: function(query) { this.searchCanceled(); }, jumpToNextSearchResult: function() { }, jumpToPreviousSearchResult: function() { }, canSearchAndReplace: function() { return false; }, replaceSelectionWith: function(text) { }, replaceAllWith: function(query, text) { }, canFilter: function() { return false; }, performFilter: function(query) { }, createSidebarView: function(parentElement, position, defaultWidth) { if (this.splitView) return; if (!parentElement) parentElement = this.element; this.splitView = new WebInspector.SidebarView(position || WebInspector.SidebarView.SidebarPosition.Left, this._sidebarWidthSettingName(), defaultWidth); this.splitView.show(parentElement); this.splitView.addEventListener(WebInspector.SidebarView.EventTypes.Resized, this.sidebarResized.bind(this)); this.sidebarElement = this.splitView.sidebarElement; }, createSidebarViewWithTree: function(parentElement, position, defaultWidth) { if (this.splitView) return; this.createSidebarView(parentElement, position); this.sidebarTreeElement = document.createElement("ol"); this.sidebarTreeElement.className = "sidebar-tree"; this.splitView.sidebarElement.appendChild(this.sidebarTreeElement); this.splitView.sidebarElement.addStyleClass("sidebar"); this.sidebarTree = new TreeOutline(this.sidebarTreeElement); this.sidebarTree.panel = this; }, _sidebarWidthSettingName: function() { return this._panelName + "SidebarWidth"; }, get statusBarItems() { }, sidebarResized: function(width) { }, statusBarResized: function() { }, canShowAnchorLocation: function(anchor) { return false; }, showAnchorLocation: function(anchor) { }, elementsToRestoreScrollPositionsFor: function() { return []; }, handleShortcut: function(event) { var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(event); var handler = this._shortcuts[shortcutKey]; if (handler) { handler(event); event.handled = true; } }, registerShortcut: function(key, handler) { this._shortcuts[key] = handler; }, unregisterShortcut: function(key) { delete this._shortcuts[key]; }, __proto__: WebInspector.View.prototype } WebInspector.PanelDescriptor = function(name, title, className, scriptName, panel) { this._name = name; this._title = title; this._className = className; this._scriptName = scriptName; this._panel = panel; } WebInspector.PanelDescriptor.prototype = { name: function() { return this._name; }, title: function() { return this._title; }, iconURL: function() { return this._iconURL; }, setIconURL: function(iconURL) { this._iconURL = iconURL; }, panel: function() { if (this._panel) return this._panel; if (this._scriptName) importScript(this._scriptName); this._panel = new WebInspector[this._className]; return this._panel; } } WebInspector.InspectorView = function() { WebInspector.View.call(this); this.markAsRoot(); this.element.id = "main-panels"; this.element.setAttribute("spellcheck", false); this._history = []; this._historyIterator = -1; document.addEventListener("keydown", this._keyDown.bind(this), false); document.addEventListener("keypress", this._keyPress.bind(this), false); this._panelOrder = []; this._panelDescriptors = {}; this._openBracketIdentifiers = ["U+005B", "U+00DB"].keySet(); this._closeBracketIdentifiers = ["U+005D", "U+00DD"].keySet(); this._footerElementContainer = this.element.createChild("div", "inspector-footer status-bar hidden"); this._panelsElement = this.element.createChild("div", "fill"); } WebInspector.InspectorView.Events = { PanelSelected: "PanelSelected" } WebInspector.InspectorView.prototype = { addPanel: function(panelDescriptor) { this._panelOrder.push(panelDescriptor.name()); this._panelDescriptors[panelDescriptor.name()] = panelDescriptor; WebInspector.toolbar.addPanel(panelDescriptor); }, panel: function(panelName) { var panelDescriptor = this._panelDescriptors[panelName]; if (!panelDescriptor && this._panelOrder.length) panelDescriptor = this._panelDescriptors[this._panelOrder[0]]; return panelDescriptor ? panelDescriptor.panel() : null; }, showPanel: function(panelName) { var panel = this.panel(panelName); if (panel) this.setCurrentPanel(panel); return panel; }, currentPanel: function() { return this._currentPanel; }, setCurrentPanel: function(x) { if (this._currentPanel === x) return; if (this._currentPanel) this._currentPanel.detach(); this._currentPanel = x; if (x) { x.show(); this.dispatchEventToListeners(WebInspector.InspectorView.Events.PanelSelected); WebInspector.searchController.cancelSearch(); } for (var panelName in WebInspector.panels) { if (WebInspector.panels[panelName] === x) { WebInspector.settings.lastActivePanel.set(panelName); this._pushToHistory(panelName); WebInspector.userMetrics.panelShown(panelName); } } }, _keyPress: function(event) { clearTimeout(this._keyDownTimer); delete this._keyDownTimer; }, _keyDown: function(event) { if (!WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event)) return; if (!event.shiftKey && !event.altKey && event.keyCode > 0x30 && event.keyCode < 0x3A) { var panelName = this._panelOrder[event.keyCode - 0x31]; if (panelName) { this.showPanel(panelName); event.consume(true); } return; } if (!WebInspector.isWin() || (!this._openBracketIdentifiers[event.keyIdentifier] && !this._closeBracketIdentifiers[event.keyIdentifier])) { this._keyDownInternal(event); return; } this._keyDownTimer = setTimeout(this._keyDownInternal.bind(this, event), 0); }, _keyDownInternal: function(event) { if (this._openBracketIdentifiers[event.keyIdentifier]) { var isRotateLeft = !event.shiftKey && !event.altKey; if (isRotateLeft) { var index = this._panelOrder.indexOf(this.currentPanel().name); index = (index === 0) ? this._panelOrder.length - 1 : index - 1; this.showPanel(this._panelOrder[index]); event.consume(true); return; } var isGoBack = event.altKey; if (isGoBack && this._canGoBackInHistory()) { this._goBackInHistory(); event.consume(true); } return; } if (this._closeBracketIdentifiers[event.keyIdentifier]) { var isRotateRight = !event.shiftKey && !event.altKey; if (isRotateRight) { var index = this._panelOrder.indexOf(this.currentPanel().name); index = (index + 1) % this._panelOrder.length; this.showPanel(this._panelOrder[index]); event.consume(true); return; } var isGoForward = event.altKey; if (isGoForward && this._canGoForwardInHistory()) { this._goForwardInHistory(); event.consume(true); } return; } }, _canGoBackInHistory: function() { return this._historyIterator > 0; }, _goBackInHistory: function() { this._inHistory = true; this.setCurrentPanel(WebInspector.panels[this._history[--this._historyIterator]]); delete this._inHistory; }, _canGoForwardInHistory: function() { return this._historyIterator < this._history.length - 1; }, _goForwardInHistory: function() { this._inHistory = true; this.setCurrentPanel(WebInspector.panels[this._history[++this._historyIterator]]); delete this._inHistory; }, _pushToHistory: function(panelName) { if (this._inHistory) return; this._history.splice(this._historyIterator + 1, this._history.length - this._historyIterator - 1); if (!this._history.length || this._history[this._history.length - 1] !== panelName) this._history.push(panelName); this._historyIterator = this._history.length - 1; }, panelsElement: function() { return this._panelsElement; }, setFooterElement: function(element) { if (element) { this._footerElementContainer.removeStyleClass("hidden"); this._footerElementContainer.appendChild(element); this._panelsElement.style.bottom = this._footerElementContainer.offsetHeight + "px"; } else { this._footerElementContainer.addStyleClass("hidden"); this._footerElementContainer.removeChildren(); this._panelsElement.style.bottom = 0; } this.doResize(); }, showPanelForAnchorNavigation: function(panel) { WebInspector.searchController.disableSearchUntilExplicitAction(); this.setCurrentPanel(panel); }, __proto__: WebInspector.View.prototype } WebInspector.inspectorView = null; WebInspector.AdvancedSearchController = function() { this._shortcut = WebInspector.AdvancedSearchController.createShortcut(); this._searchId = 0; WebInspector.settings.advancedSearchConfig = WebInspector.settings.createSetting("advancedSearchConfig", new WebInspector.SearchConfig("", true, false)); WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this); } WebInspector.AdvancedSearchController.createShortcut = function() { if (WebInspector.isMac()) return WebInspector.KeyboardShortcut.makeDescriptor("f", WebInspector.KeyboardShortcut.Modifiers.Meta | WebInspector.KeyboardShortcut.Modifiers.Alt); else return WebInspector.KeyboardShortcut.makeDescriptor("f", WebInspector.KeyboardShortcut.Modifiers.Ctrl | WebInspector.KeyboardShortcut.Modifiers.Shift); } WebInspector.AdvancedSearchController.prototype = { handleShortcut: function(event) { if (WebInspector.KeyboardShortcut.makeKeyFromEvent(event) === this._shortcut.key) { if (!this._searchView || !this._searchView.isShowing() || this._searchView._search !== document.activeElement) { WebInspector.showPanel("scripts"); this.show(); } else this.close(); event.consume(true); return true; } return false; }, _frameNavigated: function() { this.resetSearch(); }, registerSearchScope: function(searchScope) { this._searchScope = searchScope; }, show: function() { if (!this._searchView) this._searchView = new WebInspector.SearchView(this); if (this._searchView.isShowing()) this._searchView.focus(); else WebInspector.showViewInDrawer(this._searchView._searchPanelElement, this._searchView, this.stopSearch.bind(this)); }, close: function() { this.stopSearch(); WebInspector.closeViewInDrawer(); }, _onSearchResult: function(searchId, searchResult) { if (searchId !== this._searchId) return; this._searchView.addSearchResult(searchResult); if (!searchResult.searchMatches.length) return; if (!this._searchResultsPane) this._searchResultsPane = this._currentSearchScope.createSearchResultsPane(this._searchConfig); this._searchView.resultsPane = this._searchResultsPane; this._searchResultsPane.addSearchResult(searchResult); }, _onSearchFinished: function(searchId, finished) { if (searchId !== this._searchId) return; if (!this._searchResultsPane) this._searchView.nothingFound(); this._searchView.searchFinished(finished); }, startSearch: function(searchConfig) { this.resetSearch(); ++this._searchId; this._searchConfig = searchConfig; this._currentSearchScope = this._searchScope; var totalSearchResultsCount = this._currentSearchScope.performSearch(searchConfig, this._onSearchResult.bind(this, this._searchId), this._onSearchFinished.bind(this, this._searchId)); this._searchView.searchStarted(totalSearchResultsCount); }, resetSearch: function() { this.stopSearch(); if (this._searchResultsPane) { this._searchView.resetResults(); delete this._searchResultsPane; } }, stopSearch: function() { if (this._currentSearchScope) this._currentSearchScope.stopSearch(); } } WebInspector.SearchView = function(controller) { WebInspector.View.call(this); this.registerRequiredCSS("textEditor.css"); this._controller = controller; this.element.className = "search-view"; this._searchPanelElement = document.createElement("span"); this._searchPanelElement.className = "search-drawer-header"; this._searchPanelElement.addEventListener("keydown", this._onKeyDown.bind(this), false); this._searchResultsElement = this.element.createChild("div"); this._searchResultsElement.className = "search-results"; this._searchLabel = this._searchPanelElement.createChild("span"); this._searchLabel.textContent = WebInspector.UIString("Search sources"); this._search = this._searchPanelElement.createChild("input"); this._search.setAttribute("type", "search"); this._search.addStyleClass("search-config-search"); this._search.setAttribute("results", "0"); this._search.setAttribute("size", 30); this._ignoreCaseLabel = this._searchPanelElement.createChild("label"); this._ignoreCaseLabel.addStyleClass("search-config-label"); this._ignoreCaseCheckbox = this._ignoreCaseLabel.createChild("input"); this._ignoreCaseCheckbox.setAttribute("type", "checkbox"); this._ignoreCaseCheckbox.addStyleClass("search-config-checkbox"); this._ignoreCaseLabel.appendChild(document.createTextNode(WebInspector.UIString("Ignore case"))); this._regexLabel = this._searchPanelElement.createChild("label"); this._regexLabel.addStyleClass("search-config-label"); this._regexCheckbox = this._regexLabel.createChild("input"); this._regexCheckbox.setAttribute("type", "checkbox"); this._regexCheckbox.addStyleClass("search-config-checkbox"); this._regexLabel.appendChild(document.createTextNode(WebInspector.UIString("Regular expression"))); this._searchStatusBarElement = document.createElement("div"); this._searchStatusBarElement.className = "search-status-bar-item"; this._searchMessageElement = this._searchStatusBarElement.createChild("div"); this._searchMessageElement.className = "search-status-bar-message"; this._searchResultsMessageElement = document.createElement("span"); this._searchResultsMessageElement.className = "search-results-status-bar-message"; this._load(); } WebInspector.SearchView.maxQueriesCount = 20; WebInspector.SearchView.prototype = { get statusBarItems() { return [this._searchStatusBarElement, this._searchResultsMessageElement]; }, get searchConfig() { return new WebInspector.SearchConfig(this._search.value, this._ignoreCaseCheckbox.checked, this._regexCheckbox.checked); }, set resultsPane(resultsPane) { this.resetResults(); this._searchResultsElement.appendChild(resultsPane.element); }, searchStarted: function(totalSearchResultsCount) { this.resetResults(); this._resetCounters(); this._searchMessageElement.textContent = WebInspector.UIString("Searching..."); this._progressIndicator = new WebInspector.ProgressIndicator(); this._progressIndicator.setTotalWork(totalSearchResultsCount); this._progressIndicator.show(this._searchStatusBarElement); this._updateSearchResultsMessage(); if (!this._searchingView) this._searchingView = new WebInspector.EmptyView(WebInspector.UIString("Searching...")); this._searchingView.show(this._searchResultsElement); }, _updateSearchResultsMessage: function() { if (this._searchMatchesCount && this._searchResultsCount) this._searchResultsMessageElement.textContent = WebInspector.UIString("Found %d matches in %d files.", this._searchMatchesCount, this._nonEmptySearchResultsCount); else this._searchResultsMessageElement.textContent = ""; }, resetResults: function() { if (this._searchingView) this._searchingView.detach(); if (this._notFoundView) this._notFoundView.detach(); this._searchResultsElement.removeChildren(); }, _resetCounters: function() { this._searchMatchesCount = 0; this._searchResultsCount = 0; this._nonEmptySearchResultsCount = 0; }, nothingFound: function() { this.resetResults(); if (!this._notFoundView) this._notFoundView = new WebInspector.EmptyView(WebInspector.UIString("No matches found.")); this._notFoundView.show(this._searchResultsElement); this._searchResultsMessageElement.textContent = WebInspector.UIString("No matches found."); }, addSearchResult: function(searchResult) { this._searchMatchesCount += searchResult.searchMatches.length; this._searchResultsCount++; if (searchResult.searchMatches.length) this._nonEmptySearchResultsCount++; this._updateSearchResultsMessage(); if (this._progressIndicator.isCanceled()) this._onCancel(); else this._progressIndicator.setWorked(this._searchResultsCount); }, searchFinished: function(finished) { this._progressIndicator.done(); this._searchMessageElement.textContent = finished ? WebInspector.UIString("Search finished.") : WebInspector.UIString("Search interrupted."); }, focus: function() { WebInspector.setCurrentFocusElement(this._search); this._search.select(); }, wasShown: function() { this.focus(); }, willHide: function() { this._controller.stopSearch(); }, _onKeyDown: function(event) { switch (event.keyCode) { case WebInspector.KeyboardShortcut.Keys.Enter.code: this._onAction(); break; case WebInspector.KeyboardShortcut.Keys.Esc.code: this._controller.close(); event.consume(true); break; } }, _save: function() { var searchConfig = new WebInspector.SearchConfig(this.searchConfig.query, this.searchConfig.ignoreCase, this.searchConfig.isRegex); WebInspector.settings.advancedSearchConfig.set(searchConfig); }, _load: function() { var searchConfig = WebInspector.settings.advancedSearchConfig.get(); this._search.value = searchConfig.query; this._ignoreCaseCheckbox.checked = searchConfig.ignoreCase; this._regexCheckbox.checked = searchConfig.isRegex; }, _onCancel: function() { this._controller.stopSearch(); this.focus(); }, _onAction: function() { if (!this.searchConfig.query || !this.searchConfig.query.length) return; this._save(); this._controller.startSearch(this.searchConfig); }, __proto__: WebInspector.View.prototype } WebInspector.SearchConfig = function(query, ignoreCase, isRegex) { this.query = query; this.ignoreCase = ignoreCase; this.isRegex = isRegex; } WebInspector.SearchScope = function() { } WebInspector.SearchScope.prototype = { performSearch: function(searchConfig, searchResultCallback, searchFinishedCallback) { }, stopSearch: function() { }, createSearchResultsPane: function(searchConfig) { } } WebInspector.SearchResult = function(offset, length) { this.offset = offset; this.length = length; } WebInspector.SearchResultsPane = function(searchConfig) { this._searchConfig = searchConfig; this.element = document.createElement("div"); } WebInspector.SearchResultsPane.prototype = { get searchConfig() { return this._searchConfig; }, addSearchResult: function(searchResult) { } } WebInspector.FileBasedSearchResultsPane = function(searchConfig) { WebInspector.SearchResultsPane.call(this, searchConfig); this._searchResults = []; this.element.id ="search-results-pane-file-based"; this._treeOutlineElement = document.createElement("ol"); this._treeOutlineElement.className = "search-results-outline-disclosure"; this.element.appendChild(this._treeOutlineElement); this._treeOutline = new TreeOutline(this._treeOutlineElement); this._matchesExpandedCount = 0; } WebInspector.FileBasedSearchResultsPane.matchesExpandedByDefaultCount = 20; WebInspector.FileBasedSearchResultsPane.fileMatchesShownAtOnce = 20; WebInspector.FileBasedSearchResultsPane.prototype = { _createAnchor: function(uiSourceCode, lineNumber, columnNumber) { var anchor = document.createElement("a"); anchor.preferredPanel = "scripts"; anchor.href = sanitizeHref(uiSourceCode.url); anchor.uiSourceCode = uiSourceCode; anchor.lineNumber = lineNumber; return anchor; }, addSearchResult: function(searchResult) { this._searchResults.push(searchResult); var uiSourceCode = searchResult.uiSourceCode; var searchMatches = searchResult.searchMatches; var fileTreeElement = this._addFileTreeElement(uiSourceCode.url, searchMatches.length, this._searchResults.length - 1); }, _fileTreeElementExpanded: function(searchResult, fileTreeElement) { if (fileTreeElement._initialized) return; var toIndex = Math.min(searchResult.searchMatches.length, WebInspector.FileBasedSearchResultsPane.fileMatchesShownAtOnce); if (toIndex < searchResult.searchMatches.length) { this._appendSearchMatches(fileTreeElement, searchResult, 0, toIndex - 1); this._appendShowMoreMatchesElement(fileTreeElement, searchResult, toIndex - 1); } else this._appendSearchMatches(fileTreeElement, searchResult, 0, toIndex); fileTreeElement._initialized = true; }, _appendSearchMatches: function(fileTreeElement, searchResult, fromIndex, toIndex) { var uiSourceCode = searchResult.uiSourceCode; var searchMatches = searchResult.searchMatches; var regex = createSearchRegex(this._searchConfig.query, !this._searchConfig.ignoreCase, this._searchConfig.isRegex); for (var i = fromIndex; i < toIndex; ++i) { var lineNumber = searchMatches[i].lineNumber; var lineContent = searchMatches[i].lineContent; var matchRanges = this._regexMatchRanges(lineContent, regex); var anchor = this._createAnchor(uiSourceCode, lineNumber, matchRanges[0].offset); var numberString = numberToStringWithSpacesPadding(lineNumber + 1, 4); var lineNumberSpan = document.createElement("span"); lineNumberSpan.addStyleClass("webkit-line-number"); lineNumberSpan.addStyleClass("search-match-line-number"); lineNumberSpan.textContent = numberString; anchor.appendChild(lineNumberSpan); var contentSpan = this._createContentSpan(lineContent, matchRanges); anchor.appendChild(contentSpan); var searchMatchElement = new TreeElement("", null, false); fileTreeElement.appendChild(searchMatchElement); searchMatchElement.listItemElement.className = "search-match source-code"; searchMatchElement.listItemElement.appendChild(anchor); } }, _appendShowMoreMatchesElement: function(fileTreeElement, searchResult, startMatchIndex) { var matchesLeftCount = searchResult.searchMatches.length - startMatchIndex; var showMoreMatchesText = WebInspector.UIString("Show all matches (%d more).", matchesLeftCount); var showMoreMatchesElement = new TreeElement(showMoreMatchesText, null, false); fileTreeElement.appendChild(showMoreMatchesElement); showMoreMatchesElement.listItemElement.addStyleClass("show-more-matches"); showMoreMatchesElement.onselect = this._showMoreMatchesElementSelected.bind(this, searchResult, startMatchIndex, showMoreMatchesElement); }, _showMoreMatchesElementSelected: function(searchResult, startMatchIndex, showMoreMatchesElement) { var fileTreeElement = showMoreMatchesElement.parent; fileTreeElement.removeChild(showMoreMatchesElement); this._appendSearchMatches(fileTreeElement, searchResult, startMatchIndex, searchResult.searchMatches.length); }, _addFileTreeElement: function(fileName, searchMatchesCount, searchResultIndex) { var fileTreeElement = new TreeElement("", null, true); fileTreeElement.toggleOnClick = true; fileTreeElement.selectable = false; this._treeOutline.appendChild(fileTreeElement); fileTreeElement.listItemElement.addStyleClass("search-result"); var fileNameSpan = document.createElement("span"); fileNameSpan.className = "search-result-file-name"; fileNameSpan.textContent = fileName; fileTreeElement.listItemElement.appendChild(fileNameSpan); var matchesCountSpan = document.createElement("span"); matchesCountSpan.className = "search-result-matches-count"; if (searchMatchesCount === 1) matchesCountSpan.textContent = WebInspector.UIString("(%d match)", searchMatchesCount); else matchesCountSpan.textContent = WebInspector.UIString("(%d matches)", searchMatchesCount); fileTreeElement.listItemElement.appendChild(matchesCountSpan); var searchResult = this._searchResults[searchResultIndex]; fileTreeElement.onexpand = this._fileTreeElementExpanded.bind(this, searchResult, fileTreeElement); if (this._matchesExpandedCount < WebInspector.FileBasedSearchResultsPane.matchesExpandedByDefaultCount) fileTreeElement.expand(); this._matchesExpandedCount += searchResult.searchMatches.length; return fileTreeElement; }, _regexMatchRanges: function(lineContent, regex) { regex.lastIndex = 0; var match; var offset = 0; var matchRanges = []; while ((regex.lastIndex < lineContent.length) && (match = regex.exec(lineContent))) matchRanges.push(new WebInspector.SearchResult(match.index, match[0].length)); return matchRanges; }, _createContentSpan: function(lineContent, matchRanges) { var contentSpan = document.createElement("span"); contentSpan.className = "search-match-content"; contentSpan.textContent = lineContent; WebInspector.highlightRangesWithStyleClass(contentSpan, matchRanges, "highlighted-match"); return contentSpan; }, __proto__: WebInspector.SearchResultsPane.prototype } WebInspector.FileBasedSearchResultsPane.SearchResult = function(uiSourceCode, searchMatches) { this.uiSourceCode = uiSourceCode; this.searchMatches = searchMatches; } WebInspector.advancedSearchController = null; WebInspector.TimelineGrid = function() { this.element = document.createElement("div"); this._itemsGraphsElement = document.createElement("div"); this._itemsGraphsElement.id = "resources-graphs"; this.element.appendChild(this._itemsGraphsElement); this._dividersElement = document.createElement("div"); this._dividersElement.className = "resources-dividers"; this.element.appendChild(this._dividersElement); this._gridHeaderElement = document.createElement("div"); this._eventDividersElement = document.createElement("div"); this._eventDividersElement.className = "resources-event-dividers"; this._gridHeaderElement.appendChild(this._eventDividersElement); this._dividersLabelBarElement = document.createElement("div"); this._dividersLabelBarElement.className = "resources-dividers-label-bar"; this._gridHeaderElement.appendChild(this._dividersLabelBarElement); this.element.appendChild(this._gridHeaderElement); } WebInspector.TimelineGrid.prototype = { get itemsGraphsElement() { return this._itemsGraphsElement; }, get dividersElement() { return this._dividersElement; }, get dividersLabelBarElement() { return this._dividersLabelBarElement; }, get gridHeaderElement() { return this._gridHeaderElement; }, removeDividers: function() { this._dividersElement.removeChildren(); this._dividersLabelBarElement.removeChildren(); }, updateDividers: function(calculator) { var dividersElementClientWidth = this._dividersElement.clientWidth; var dividerCount = Math.round(dividersElementClientWidth / 64); var slice = calculator.boundarySpan() / dividerCount; this._currentDividerSlice = slice; var divider = this._dividersElement.firstChild; var dividerLabelBar = this._dividersLabelBarElement.firstChild; var paddingLeft = calculator.paddingLeft; for (var i = paddingLeft ? 0 : 1; i <= dividerCount; ++i) { if (!divider) { divider = document.createElement("div"); divider.className = "resources-divider"; this._dividersElement.appendChild(divider); dividerLabelBar = document.createElement("div"); dividerLabelBar.className = "resources-divider"; var label = document.createElement("div"); label.className = "resources-divider-label"; dividerLabelBar._labelElement = label; dividerLabelBar.appendChild(label); this._dividersLabelBarElement.appendChild(dividerLabelBar); } if (i === (paddingLeft ? 0 : 1)) { divider.addStyleClass("first"); dividerLabelBar.addStyleClass("first"); } else { divider.removeStyleClass("first"); dividerLabelBar.removeStyleClass("first"); } if (i === dividerCount) { divider.addStyleClass("last"); dividerLabelBar.addStyleClass("last"); } else { divider.removeStyleClass("last"); dividerLabelBar.removeStyleClass("last"); } var left; if (!slice) { left = dividersElementClientWidth / dividerCount * i + paddingLeft; dividerLabelBar._labelElement.textContent = ""; } else { left = calculator.computePosition(calculator.minimumBoundary() + slice * i); dividerLabelBar._labelElement.textContent = calculator.formatTime(slice * i); } var percentLeft = 100 * left / dividersElementClientWidth; this._setDividerAndBarLeft(divider, dividerLabelBar, percentLeft); divider = divider.nextSibling; dividerLabelBar = dividerLabelBar.nextSibling; } while (divider) { var nextDivider = divider.nextSibling; this._dividersElement.removeChild(divider); divider = nextDivider; } while (dividerLabelBar) { var nextDivider = dividerLabelBar.nextSibling; this._dividersLabelBarElement.removeChild(dividerLabelBar); dividerLabelBar = nextDivider; } return true; }, _setDividerAndBarLeft: function(divider, dividerLabelBar, percentLeft) { var percentStyleLeft = parseFloat(divider.style.left); if (!isNaN(percentStyleLeft) && Math.abs(percentStyleLeft - percentLeft) < 0.1) return; divider.style.left = percentLeft + "%"; dividerLabelBar.style.left = percentLeft + "%"; }, addEventDivider: function(divider) { this._eventDividersElement.appendChild(divider); }, addEventDividers: function(dividers) { this._gridHeaderElement.removeChild(this._eventDividersElement); for (var i = 0; i < dividers.length; ++i) { if (dividers[i]) this._eventDividersElement.appendChild(dividers[i]); } this._gridHeaderElement.appendChild(this._eventDividersElement); }, removeEventDividers: function() { this._eventDividersElement.removeChildren(); }, hideEventDividers: function() { this._eventDividersElement.addStyleClass("hidden"); }, showEventDividers: function() { this._eventDividersElement.removeStyleClass("hidden"); }, setScrollAndDividerTop: function(scrollTop, dividersTop) { this._dividersElement.style.top = scrollTop + "px"; } } WebInspector.TimelineGrid.Calculator = function() { } WebInspector.TimelineGrid.Calculator.prototype = { computePosition: function(time) { }, formatTime: function(time) { }, minimumBoundary: function() { }, maximumBoundary: function() { }, boundarySpan: function() { } } WebInspector.ContentProvider = function() { } WebInspector.ContentProvider.prototype = { contentURL: function() { }, contentType: function() { }, requestContent: function(callback) { }, searchInContent: function(query, caseSensitive, isRegex, callback) { } } WebInspector.ContentProvider.SearchMatch = function(lineNumber, lineContent) { this.lineNumber = lineNumber; this.lineContent = lineContent; } WebInspector.Resource = function(request, url, documentURL, frameId, loaderId, type, mimeType, isHidden) { this._request = request; this.url = url; this._documentURL = documentURL; this._frameId = frameId; this._loaderId = loaderId; this._type = type || WebInspector.resourceTypes.Other; this._mimeType = mimeType; this._isHidden = isHidden; this._content; this._contentEncoded; this._pendingContentCallbacks = []; if (this._request && !this._request.finished) this._request.addEventListener(WebInspector.NetworkRequest.Events.FinishedLoading, this._requestFinished, this); } WebInspector.Resource.Events = { MessageAdded: "message-added", MessagesCleared: "messages-cleared", } WebInspector.Resource.prototype = { get request() { return this._request; }, get url() { return this._url; }, set url(x) { this._url = x; this._parsedURL = new WebInspector.ParsedURL(x); }, get parsedURL() { return this._parsedURL; }, get documentURL() { return this._documentURL; }, get frameId() { return this._frameId; }, get loaderId() { return this._loaderId; }, get displayName() { return this._parsedURL.displayName; }, get type() { return this._request ? this._request.type : this._type; }, get mimeType() { return this._request ? this._request.mimeType : this._mimeType; }, get messages() { return this._messages || []; }, addMessage: function(msg) { if (!msg.isErrorOrWarning() || !msg.message) return; if (!this._messages) this._messages = []; this._messages.push(msg); this.dispatchEventToListeners(WebInspector.Resource.Events.MessageAdded, msg); }, get errors() { return this._errors || 0; }, set errors(x) { this._errors = x; }, get warnings() { return this._warnings || 0; }, set warnings(x) { this._warnings = x; }, clearErrorsAndWarnings: function() { this._messages = []; this._warnings = 0; this._errors = 0; this.dispatchEventToListeners(WebInspector.Resource.Events.MessagesCleared); }, get content() { return this._content; }, get contentEncoded() { return this._contentEncoded; }, contentURL: function() { return this._url; }, contentType: function() { return this.type; }, requestContent: function(callback) { if (typeof this._content !== "undefined") { callback(this._content, !!this._contentEncoded, this.canonicalMimeType()); return; } this._pendingContentCallbacks.push(callback); if (!this._request || this._request.finished) this._innerRequestContent(); }, canonicalMimeType: function() { return this.type.canonicalMimeType() || this.mimeType; }, searchInContent: function(query, caseSensitive, isRegex, callback) { function callbackWrapper(error, searchMatches) { callback(searchMatches || []); } if (this.frameId) PageAgent.searchInResource(this.frameId, this.url, query, caseSensitive, isRegex, callbackWrapper); else callback([]); }, populateImageSource: function(image) { function onResourceContent() { var imageSrc = WebInspector.contentAsDataURL(this._content, this.mimeType, this._contentEncoded); if (imageSrc === null) imageSrc = this.url; image.src = imageSrc; } this.requestContent(onResourceContent.bind(this)); }, _requestFinished: function() { this._request.removeEventListener(WebInspector.NetworkRequest.Events.FinishedLoading, this._requestFinished, this); if (this._pendingContentCallbacks.length) this._innerRequestContent(); }, _innerRequestContent: function() { if (this._contentRequested) return; this._contentRequested = true; function contentLoaded(content, contentEncoded) { this._content = content; this._contentEncoded = contentEncoded; var callbacks = this._pendingContentCallbacks.slice(); for (var i = 0; i < callbacks.length; ++i) callbacks[i](this._content, this._contentEncoded, this.canonicalMimeType()); this._pendingContentCallbacks.length = 0; delete this._contentRequested; } function resourceContentLoaded(error, content, contentEncoded) { if (error) console.error("Resource content request failed: " + error); contentLoaded.call(this, error ? null : content, contentEncoded); } if (this.request) { function requestContentLoaded(content, contentEncoded, mimeType) { contentLoaded.call(this, content, contentEncoded); } this.request.requestContent(requestContentLoaded.bind(this)); return; } PageAgent.getResourceContent(this.frameId, this.url, resourceContentLoaded.bind(this)); }, isHidden: function() { return !!this._isHidden; }, __proto__: WebInspector.Object.prototype } WebInspector.NetworkRequest = function(requestId, url, documentURL, frameId, loaderId) { this._requestId = requestId; this.url = url; this._documentURL = documentURL; this._frameId = frameId; this._loaderId = loaderId; this._startTime = -1; this._endTime = -1; this.statusCode = 0; this.statusText = ""; this.requestMethod = ""; this.requestTime = 0; this.receiveHeadersEnd = 0; this._type = WebInspector.resourceTypes.Other; this._contentEncoded = false; this._pendingContentCallbacks = []; this._frames = []; } WebInspector.NetworkRequest.Events = { FinishedLoading: "FinishedLoading", TimingChanged: "TimingChanged", RequestHeadersChanged: "RequestHeadersChanged", ResponseHeadersChanged: "ResponseHeadersChanged", } WebInspector.NetworkRequest.prototype = { get requestId() { return this._requestId; }, set requestId(requestId) { this._requestId = requestId; }, get url() { return this._url; }, set url(x) { if (this._url === x) return; this._url = x; this._parsedURL = new WebInspector.ParsedURL(x); delete this._parsedQueryParameters; delete this._name; delete this._path; }, get documentURL() { return this._documentURL; }, get parsedURL() { return this._parsedURL; }, get frameId() { return this._frameId; }, get loaderId() { return this._loaderId; }, get startTime() { return this._startTime || -1; }, set startTime(x) { this._startTime = x; }, get responseReceivedTime() { return this._responseReceivedTime || -1; }, set responseReceivedTime(x) { this._responseReceivedTime = x; }, get endTime() { return this._endTime || -1; }, set endTime(x) { if (this.timing && this.timing.requestTime) { this._endTime = Math.max(x, this.responseReceivedTime); } else { this._endTime = x; if (this._responseReceivedTime > x) this._responseReceivedTime = x; } }, get duration() { if (this._endTime === -1 || this._startTime === -1) return -1; return this._endTime - this._startTime; }, get latency() { if (this._responseReceivedTime === -1 || this._startTime === -1) return -1; return this._responseReceivedTime - this._startTime; }, get receiveDuration() { if (this._endTime === -1 || this._responseReceivedTime === -1) return -1; return this._endTime - this._responseReceivedTime; }, get resourceSize() { return this._resourceSize || 0; }, set resourceSize(x) { this._resourceSize = x; }, get transferSize() { if (this.cached) return 0; if (this.statusCode === 304) return this.responseHeadersSize; if (this._transferSize !== undefined) return this._transferSize; var bodySize = Number(this.responseHeaderValue("Content-Length") || this.resourceSize); return this.responseHeadersSize + bodySize; }, increaseTransferSize: function(x) { this._transferSize = (this._transferSize || 0) + x; }, get finished() { return this._finished; }, set finished(x) { if (this._finished === x) return; this._finished = x; if (x) { this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.FinishedLoading, this); if (this._pendingContentCallbacks.length) this._innerRequestContent(); } }, get failed() { return this._failed; }, set failed(x) { this._failed = x; }, get canceled() { return this._canceled; }, set canceled(x) { this._canceled = x; }, get cached() { return this._cached; }, set cached(x) { this._cached = x; if (x) delete this._timing; }, get timing() { return this._timing; }, set timing(x) { if (x && !this._cached) { this._startTime = x.requestTime; this._responseReceivedTime = x.requestTime + x.receiveHeadersEnd / 1000.0; this._timing = x; this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.TimingChanged, this); } }, get mimeType() { return this._mimeType; }, set mimeType(x) { this._mimeType = x; }, get displayName() { return this._parsedURL.displayName; }, name: function() { if (this._name) return this._name; this._parseNameAndPathFromURL(); return this._name; }, path: function() { if (this._path) return this._path; this._parseNameAndPathFromURL(); return this._path; }, _parseNameAndPathFromURL: function() { if (this._parsedURL.isDataURL()) { this._name = this._parsedURL.dataURLDisplayName(); this._path = ""; } else if (this._parsedURL.isAboutBlank()) { this._name = this._parsedURL.url; this._path = ""; } else { this._path = this._parsedURL.host + this._parsedURL.folderPathComponents; this._path = this._path.trimURL(WebInspector.inspectedPageDomain ? WebInspector.inspectedPageDomain : ""); if (this._parsedURL.lastPathComponent || this._parsedURL.queryParams) this._name = this._parsedURL.lastPathComponent + (this._parsedURL.queryParams ? "?" + this._parsedURL.queryParams : ""); else if (this._parsedURL.folderPathComponents) { this._name = this._parsedURL.folderPathComponents.substring(this._parsedURL.folderPathComponents.lastIndexOf("/") + 1) + "/"; this._path = this._path.substring(0, this._path.lastIndexOf("/")); } else { this._name = this._parsedURL.host; this._path = ""; } } }, get folder() { var path = this._parsedURL.path; var indexOfQuery = path.indexOf("?"); if (indexOfQuery !== -1) path = path.substring(0, indexOfQuery); var lastSlashIndex = path.lastIndexOf("/"); return lastSlashIndex !== -1 ? path.substring(0, lastSlashIndex) : ""; }, get type() { return this._type; }, set type(x) { this._type = x; }, get redirectSource() { if (this.redirects && this.redirects.length > 0) return this.redirects[this.redirects.length - 1]; return this._redirectSource; }, set redirectSource(x) { this._redirectSource = x; }, get requestHeaders() { return this._requestHeaders || []; }, set requestHeaders(x) { this._requestHeaders = x; delete this._sortedRequestHeaders; delete this._requestCookies; this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.RequestHeadersChanged); }, get requestHeadersText() { if (typeof this._requestHeadersText === "undefined") { this._requestHeadersText = this.requestMethod + " " + this.url + " HTTP/1.1\r\n"; for (var i = 0; i < this.requestHeaders.length; ++i) this._requestHeadersText += this.requestHeaders[i].name + ": " + this.requestHeaders[i].value + "\r\n"; } return this._requestHeadersText; }, set requestHeadersText(x) { this._requestHeadersText = x; this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.RequestHeadersChanged); }, get requestHeadersSize() { return this.requestHeadersText.length; }, get sortedRequestHeaders() { if (this._sortedRequestHeaders !== undefined) return this._sortedRequestHeaders; this._sortedRequestHeaders = []; this._sortedRequestHeaders = this.requestHeaders.slice(); this._sortedRequestHeaders.sort(function(a,b) { return a.name.toLowerCase().localeCompare(b.name.toLowerCase()) }); return this._sortedRequestHeaders; }, requestHeaderValue: function(headerName) { return this._headerValue(this.requestHeaders, headerName); }, get requestCookies() { if (!this._requestCookies) this._requestCookies = WebInspector.CookieParser.parseCookie(this.requestHeaderValue("Cookie")); return this._requestCookies; }, get requestFormData() { return this._requestFormData; }, set requestFormData(x) { this._requestFormData = x; delete this._parsedFormParameters; }, get requestHttpVersion() { var firstLine = this.requestHeadersText.split(/\r\n/)[0]; var match = firstLine.match(/(HTTP\/\d+\.\d+)$/); return match ? match[1] : undefined; }, get responseHeaders() { return this._responseHeaders || []; }, set responseHeaders(x) { this._responseHeaders = x; delete this._sortedResponseHeaders; delete this._responseCookies; this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.ResponseHeadersChanged); }, get responseHeadersText() { if (typeof this._responseHeadersText === "undefined") { this._responseHeadersText = "HTTP/1.1 " + this.statusCode + " " + this.statusText + "\r\n"; for (var i = 0; i < this.responseHeaders.length; ++i) this._responseHeadersText += this.responseHeaders[i].name + ": " + this.responseHeaders[i].value + "\r\n"; } return this._responseHeadersText; }, set responseHeadersText(x) { this._responseHeadersText = x; this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.ResponseHeadersChanged); }, get responseHeadersSize() { return this.responseHeadersText.length; }, get sortedResponseHeaders() { if (this._sortedResponseHeaders !== undefined) return this._sortedResponseHeaders; this._sortedResponseHeaders = []; this._sortedResponseHeaders = this.responseHeaders.slice(); this._sortedResponseHeaders.sort(function(a,b) { return a.name.toLowerCase().localeCompare(b.name.toLowerCase()) }); return this._sortedResponseHeaders; }, responseHeaderValue: function(headerName) { return this._headerValue(this.responseHeaders, headerName); }, get responseCookies() { if (!this._responseCookies) this._responseCookies = WebInspector.CookieParser.parseSetCookie(this.responseHeaderValue("Set-Cookie")); return this._responseCookies; }, queryString: function() { if (this._queryString) return this._queryString; var queryString = this.url.split("?", 2)[1]; if (!queryString) return null; this._queryString = queryString.split("#", 2)[0]; return this._queryString; }, get queryParameters() { if (this._parsedQueryParameters) return this._parsedQueryParameters; var queryString = this.queryString(); if (!queryString) return null; this._parsedQueryParameters = this._parseParameters(queryString); return this._parsedQueryParameters; }, get formParameters() { if (this._parsedFormParameters) return this._parsedFormParameters; if (!this.requestFormData) return null; var requestContentType = this.requestContentType(); if (!requestContentType || !requestContentType.match(/^application\/x-www-form-urlencoded\s*(;.*)?$/i)) return null; this._parsedFormParameters = this._parseParameters(this.requestFormData); return this._parsedFormParameters; }, get responseHttpVersion() { var match = this.responseHeadersText.match(/^(HTTP\/\d+\.\d+)/); return match ? match[1] : undefined; }, _parseParameters: function(queryString) { function parseNameValue(pair) { var parameter = {}; var splitPair = pair.split("=", 2); parameter.name = splitPair[0]; if (splitPair.length === 1) parameter.value = ""; else parameter.value = splitPair[1]; return parameter; } return queryString.split("&").map(parseNameValue); }, _headerValue: function(headers, headerName) { headerName = headerName.toLowerCase(); var values = []; for (var i = 0; i < headers.length; ++i) { if (headers[i].name.toLowerCase() === headerName) values.push(headers[i].value); } if (headerName === "set-cookie") return values.join("\n"); return values.join(", "); }, get content() { return this._content; }, get contentEncoded() { return this._contentEncoded; }, contentURL: function() { return this._url; }, contentType: function() { return this._type; }, requestContent: function(callback) { if (this.type === WebInspector.resourceTypes.WebSocket) { callback(null, false, this._mimeType); return; } if (typeof this._content !== "undefined") { callback(this.content || null, this._contentEncoded, this._mimeType); return; } this._pendingContentCallbacks.push(callback); if (this.finished) this._innerRequestContent(); }, searchInContent: function(query, caseSensitive, isRegex, callback) { callback([]); }, isHttpFamily: function() { return !!this.url.match(/^https?:/i); }, requestContentType: function() { return this.requestHeaderValue("Content-Type"); }, isPingRequest: function() { return "text/ping" === this.requestContentType(); }, hasErrorStatusCode: function() { return this.statusCode >= 400; }, populateImageSource: function(image) { function onResourceContent(content, contentEncoded, mimeType) { var imageSrc = this.asDataURL(); if (imageSrc === null) imageSrc = this.url; image.src = imageSrc; } this.requestContent(onResourceContent.bind(this)); }, asDataURL: function() { return WebInspector.contentAsDataURL(this._content, this.mimeType, this._contentEncoded); }, _innerRequestContent: function() { if (this._contentRequested) return; this._contentRequested = true; function onResourceContent(error, content, contentEncoded) { this._content = error ? null : content; this._contentEncoded = contentEncoded; var callbacks = this._pendingContentCallbacks.slice(); for (var i = 0; i < callbacks.length; ++i) callbacks[i](this._content, this._contentEncoded, this._mimeType); this._pendingContentCallbacks.length = 0; delete this._contentRequested; } NetworkAgent.getResponseBody(this._requestId, onResourceContent.bind(this)); }, frames: function() { return this._frames; }, frame: function(position) { return this._frames[position]; }, addFrameError: function(errorMessage, time) { var errorObject = {}; errorObject.errorMessage = errorMessage; errorObject.time = time; this._pushFrame(errorObject); }, addFrame: function(response, time, sent) { response.time = time; if (sent) response.sent = true; this._pushFrame(response); }, _pushFrame: function(object) { if (this._frames.length >= 100) { this._frames.splice(0, 10); } this._frames.push(object); }, __proto__: WebInspector.Object.prototype } WebInspector.UISourceCode = function(workspace, url, contentType, isEditable) { this._workspace = workspace; this._url = url; this._parsedURL = new WebInspector.ParsedURL(url); this._contentType = contentType; this._isEditable = isEditable; this._requestContentCallbacks = []; this._liveLocations = []; this._consoleMessages = []; this.history = []; if (this.isEditable() && this._url) this._restoreRevisionHistory(); this._formatterMapping = new WebInspector.IdentityFormatterSourceMapping(); } WebInspector.UISourceCode.Events = { FormattedChanged: "FormattedChanged", WorkingCopyChanged: "WorkingCopyChanged", WorkingCopyCommitted: "WorkingCopyCommitted", TitleChanged: "TitleChanged", ConsoleMessageAdded: "ConsoleMessageAdded", ConsoleMessageRemoved: "ConsoleMessageRemoved", ConsoleMessagesCleared: "ConsoleMessagesCleared", SourceMappingChanged: "SourceMappingChanged", } WebInspector.UISourceCode.prototype = { get url() { return this._url; }, urlChanged: function(url) { this._url = url; this._parsedURL = new WebInspector.ParsedURL(this._url); this.dispatchEventToListeners(WebInspector.UISourceCode.Events.TitleChanged, null); }, get parsedURL() { return this._parsedURL; }, contentURL: function() { return this._url; }, contentType: function() { return this._contentType; }, scriptFile: function() { return this._scriptFile; }, setScriptFile: function(scriptFile) { this._scriptFile = scriptFile; }, styleFile: function() { return this._styleFile; }, setStyleFile: function(styleFile) { this._styleFile = styleFile; }, requestContent: function(callback) { if (this._content || this._contentLoaded) { callback(this._content, false, this._mimeType); return; } this._requestContentCallbacks.push(callback); if (this._requestContentCallbacks.length === 1) this._workspace.requestFileContent(this, this._fireContentAvailable.bind(this)); }, requestOriginalContent: function(callback) { this._workspace.requestFileContent(this, callback); }, _commitContent: function(content) { this._content = content; this._contentLoaded = true; var lastRevision = this.history.length ? this.history[this.history.length - 1] : null; if (!lastRevision || lastRevision._content !== this._content) { var revision = new WebInspector.Revision(this, this._content, new Date()); this.history.push(revision); revision._persist(); } var oldWorkingCopy = this._workingCopy; delete this._workingCopy; this.dispatchEventToListeners(WebInspector.UISourceCode.Events.WorkingCopyCommitted, {oldWorkingCopy: oldWorkingCopy, workingCopy: this.workingCopy()}); this._workspace.dispatchEventToListeners(WebInspector.Workspace.Events.UISourceCodeContentCommitted, { uiSourceCode: this, content: this._content }); if (this._url && WebInspector.fileManager.isURLSaved(this._url)) { WebInspector.fileManager.save(this._url, this._content, false); WebInspector.fileManager.close(this._url); } }, addRevision: function(content) { this._commitContent(content); }, _restoreRevisionHistory: function() { if (!window.localStorage) return; var registry = WebInspector.Revision._revisionHistoryRegistry(); var historyItems = registry[this.url]; if (!historyItems || !historyItems.length) return; for (var i = 0; i < historyItems.length; ++i) { var content = window.localStorage[historyItems[i].key]; var timestamp = new Date(historyItems[i].timestamp); var revision = new WebInspector.Revision(this, content, timestamp); this.history.push(revision); } this._content = this.history[this.history.length - 1].content; this._contentLoaded = true; this._mimeType = this.canonicalMimeType(); }, _clearRevisionHistory: function() { if (!window.localStorage) return; var registry = WebInspector.Revision._revisionHistoryRegistry(); var historyItems = registry[this.url]; for (var i = 0; historyItems && i < historyItems.length; ++i) delete window.localStorage[historyItems[i].key]; delete registry[this.url]; window.localStorage["revision-history"] = JSON.stringify(registry); }, revertToOriginal: function() { function callback(content, contentEncoded, mimeType) { if (typeof content !== "string") return; this.addRevision(content); } this.requestOriginalContent(callback.bind(this)); }, revertAndClearHistory: function(callback) { function revert(content, contentEncoded, mimeType) { if (typeof content !== "string") return; this.addRevision(content); this._clearRevisionHistory(); this.history = []; callback(this); } this.requestOriginalContent(revert.bind(this)); }, isEditable: function() { return this._isEditable; }, workingCopy: function() { if (this.isDirty()) return this._workingCopy; return this._content; }, setWorkingCopy: function(newWorkingCopy) { var wasDirty = this.isDirty(); this._mimeType = this.canonicalMimeType(); var oldWorkingCopy = this._workingCopy; if (this._content === newWorkingCopy) delete this._workingCopy; else this._workingCopy = newWorkingCopy; this.dispatchEventToListeners(WebInspector.UISourceCode.Events.WorkingCopyChanged, {oldWorkingCopy: oldWorkingCopy, workingCopy: this.workingCopy(), wasDirty: wasDirty}); }, commitWorkingCopy: function(callback) { if (!this.isDirty()) { callback(null); return; } this._commitContent(this._workingCopy); callback(null); }, isDirty: function() { return typeof this._workingCopy !== "undefined" && this._workingCopy !== this._content; }, mimeType: function() { return this._mimeType; }, canonicalMimeType: function() { return this.contentType().canonicalMimeType() || this._mimeType; }, content: function() { return this._content; }, searchInContent: function(query, caseSensitive, isRegex, callback) { var content = this.content(); if (content) { var provider = new WebInspector.StaticContentProvider(this.contentType(), content); provider.searchInContent(query, caseSensitive, isRegex, callback); return; } this._workspace.searchInFileContent(this, query, caseSensitive, isRegex, callback); }, _fireContentAvailable: function(content, contentEncoded, mimeType) { this._contentLoaded = true; this._mimeType = mimeType; this._content = content; var callbacks = this._requestContentCallbacks.slice(); this._requestContentCallbacks = []; for (var i = 0; i < callbacks.length; ++i) callbacks[i](content, contentEncoded, mimeType); if (this._formatOnLoad) { delete this._formatOnLoad; this.setFormatted(true); } }, contentLoaded: function() { return this._contentLoaded; }, uiLocationToRawLocation: function(lineNumber, columnNumber) { if (!this._sourceMapping) return null; var location = this._formatterMapping.formattedToOriginal(lineNumber, columnNumber); return this._sourceMapping.uiLocationToRawLocation(this, location[0], location[1]); }, addLiveLocation: function(liveLocation) { this._liveLocations.push(liveLocation); }, removeLiveLocation: function(liveLocation) { this._liveLocations.remove(liveLocation); }, updateLiveLocations: function() { var locationsCopy = this._liveLocations.slice(); for (var i = 0; i < locationsCopy.length; ++i) locationsCopy[i].update(); }, overrideLocation: function(uiLocation) { var location = this._formatterMapping.originalToFormatted(uiLocation.lineNumber, uiLocation.columnNumber); uiLocation.lineNumber = location[0]; uiLocation.columnNumber = location[1]; return uiLocation; }, consoleMessages: function() { return this._consoleMessages; }, consoleMessageAdded: function(message) { this._consoleMessages.push(message); this.dispatchEventToListeners(WebInspector.UISourceCode.Events.ConsoleMessageAdded, message); }, consoleMessageRemoved: function(message) { this._consoleMessages.remove(message); this.dispatchEventToListeners(WebInspector.UISourceCode.Events.ConsoleMessageRemoved, message); }, consoleMessagesCleared: function() { this._consoleMessages = []; this.dispatchEventToListeners(WebInspector.UISourceCode.Events.ConsoleMessagesCleared); }, formatted: function() { return !!this._formatted; }, setFormatted: function(formatted) { if (!this.contentLoaded()) { this._formatOnLoad = formatted; return; } if (this._formatted === formatted) return; this._formatted = formatted; this._contentLoaded = false; this._content = false; WebInspector.UISourceCode.prototype.requestContent.call(this, didGetContent.bind(this)); function didGetContent(content, contentEncoded, mimeType) { var formatter; if (!formatted) formatter = new WebInspector.IdentityFormatter(); else formatter = WebInspector.Formatter.createFormatter(this.contentType()); formatter.formatContent(mimeType, content || "", formattedChanged.bind(this)); function formattedChanged(content, formatterMapping) { this._content = content; delete this._workingCopy; this._formatterMapping = formatterMapping; this.dispatchEventToListeners(WebInspector.UISourceCode.Events.FormattedChanged, {content: content}); this.updateLiveLocations(); } } }, createFormatter: function() { return null; }, setSourceMapping: function(sourceMapping) { this._sourceMapping = sourceMapping; this.dispatchEventToListeners(WebInspector.UISourceCode.Events.SourceMappingChanged, null); }, __proto__: WebInspector.Object.prototype } WebInspector.UISourceCodeProvider = function() { } WebInspector.UISourceCodeProvider.Events = { UISourceCodeAdded: "UISourceCodeAdded", TemporaryUISourceCodeAdded: "TemporaryUISourceCodeAdded", TemporaryUISourceCodeRemoved: "TemporaryUISourceCodeRemoved", UISourceCodeRemoved: "UISourceCodeRemoved" } WebInspector.UISourceCodeProvider.prototype = { uiSourceCodes: function() {}, addEventListener: function(eventType, listener, thisObject) { }, removeEventListener: function(eventType, listener, thisObject) { } } WebInspector.UILocation = function(uiSourceCode, lineNumber, columnNumber) { this.uiSourceCode = uiSourceCode; this.lineNumber = lineNumber; this.columnNumber = columnNumber; } WebInspector.UILocation.prototype = { uiLocationToRawLocation: function() { return this.uiSourceCode.uiLocationToRawLocation(this.lineNumber, this.columnNumber); }, url: function() { return this.uiSourceCode.contentURL(); } } WebInspector.RawLocation = function() { } WebInspector.LiveLocation = function(rawLocation, updateDelegate) { this._rawLocation = rawLocation; this._updateDelegate = updateDelegate; this._uiSourceCodes = []; } WebInspector.LiveLocation.prototype = { update: function() { var uiLocation = this.uiLocation(); if (uiLocation) { var uiSourceCode = uiLocation.uiSourceCode; if (this._uiSourceCodes.indexOf(uiSourceCode) === -1) { uiSourceCode.addLiveLocation(this); this._uiSourceCodes.push(uiSourceCode); } var oneTime = this._updateDelegate(uiLocation); if (oneTime) this.dispose(); } }, rawLocation: function() { return this._rawLocation; }, uiLocation: function() { }, dispose: function() { for (var i = 0; i < this._uiSourceCodes.length; ++i) this._uiSourceCodes[i].removeLiveLocation(this); this._uiSourceCodes = []; } } WebInspector.Revision = function(uiSourceCode, content, timestamp) { this._uiSourceCode = uiSourceCode; this._content = content; this._timestamp = timestamp; } WebInspector.Revision._revisionHistoryRegistry = function() { if (!WebInspector.Revision._revisionHistoryRegistryObject) { if (window.localStorage) { var revisionHistory = window.localStorage["revision-history"]; try { WebInspector.Revision._revisionHistoryRegistryObject = revisionHistory ? JSON.parse(revisionHistory) : {}; } catch (e) { WebInspector.Revision._revisionHistoryRegistryObject = {}; } } else WebInspector.Revision._revisionHistoryRegistryObject = {}; } return WebInspector.Revision._revisionHistoryRegistryObject; } WebInspector.Revision.filterOutStaleRevisions = function() { if (!window.localStorage) return; var registry = WebInspector.Revision._revisionHistoryRegistry(); var filteredRegistry = {}; for (var url in registry) { var historyItems = registry[url]; var filteredHistoryItems = []; for (var i = 0; historyItems && i < historyItems.length; ++i) { var historyItem = historyItems[i]; if (historyItem.loaderId === WebInspector.resourceTreeModel.mainFrame.loaderId) { filteredHistoryItems.push(historyItem); filteredRegistry[url] = filteredHistoryItems; } else delete window.localStorage[historyItem.key]; } } WebInspector.Revision._revisionHistoryRegistryObject = filteredRegistry; function persist() { window.localStorage["revision-history"] = JSON.stringify(filteredRegistry); } setTimeout(persist, 0); } WebInspector.Revision.prototype = { get uiSourceCode() { return this._uiSourceCode; }, get timestamp() { return this._timestamp; }, get content() { return this._content || null; }, revertToThis: function() { function revert(content) { if (this._uiSourceCode._content !== content) this._uiSourceCode.addRevision(content); } this.requestContent(revert.bind(this)); }, contentURL: function() { return this._uiSourceCode.url; }, contentType: function() { return this._uiSourceCode.contentType(); }, requestContent: function(callback) { callback(this._content || "", false, this.uiSourceCode.canonicalMimeType()); }, searchInContent: function(query, caseSensitive, isRegex, callback) { callback([]); }, _persist: function() { if (!window.localStorage) return; var url = this.contentURL(); if (!url || url.startsWith("inspector://")) return; var loaderId = WebInspector.resourceTreeModel.mainFrame.loaderId; var timestamp = this.timestamp.getTime(); var key = "revision-history|" + url + "|" + loaderId + "|" + timestamp; var registry = WebInspector.Revision._revisionHistoryRegistry(); var historyItems = registry[url]; if (!historyItems) { historyItems = []; registry[url] = historyItems; } historyItems.push({url: url, loaderId: loaderId, timestamp: timestamp, key: key}); function persist() { window.localStorage[key] = this._content; window.localStorage["revision-history"] = JSON.stringify(registry); } setTimeout(persist.bind(this), 0); } } WebInspector.CSSStyleModel = function() { this._pendingCommandsMajorState = []; this._locations = []; this._sourceMappings = {}; WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.UndoRedoRequested, this._undoRedoRequested, this); WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.UndoRedoCompleted, this._undoRedoCompleted, this); this._resourceBinding = new WebInspector.CSSStyleModelResourceBinding(); this._namedFlowCollections = {}; WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.DocumentUpdated, this._resetNamedFlowCollections, this); InspectorBackend.registerCSSDispatcher(new WebInspector.CSSDispatcher(this)); CSSAgent.enable(); } WebInspector.CSSStyleModel.parseRuleArrayPayload = function(ruleArray) { var result = []; for (var i = 0; i < ruleArray.length; ++i) result.push(WebInspector.CSSRule.parsePayload(ruleArray[i])); return result; } WebInspector.CSSStyleModel.parseRuleMatchArrayPayload = function(matchArray) { var result = []; for (var i = 0; i < matchArray.length; ++i) result.push(WebInspector.CSSRule.parsePayload(matchArray[i].rule, matchArray[i].matchingSelectors)); return result; } WebInspector.CSSStyleModel.Events = { StyleSheetChanged: "StyleSheetChanged", MediaQueryResultChanged: "MediaQueryResultChanged", NamedFlowCreated: "NamedFlowCreated", NamedFlowRemoved: "NamedFlowRemoved", RegionLayoutUpdated: "RegionLayoutUpdated" } WebInspector.CSSStyleModel.prototype = { getMatchedStylesAsync: function(nodeId, needPseudo, needInherited, userCallback) { function callback(userCallback, error, matchedPayload, pseudoPayload, inheritedPayload) { if (error) { if (userCallback) userCallback(null); return; } var result = {}; if (matchedPayload) result.matchedCSSRules = WebInspector.CSSStyleModel.parseRuleMatchArrayPayload(matchedPayload); if (pseudoPayload) { result.pseudoElements = []; for (var i = 0; i < pseudoPayload.length; ++i) { var entryPayload = pseudoPayload[i]; result.pseudoElements.push({ pseudoId: entryPayload.pseudoId, rules: WebInspector.CSSStyleModel.parseRuleMatchArrayPayload(entryPayload.matches) }); } } if (inheritedPayload) { result.inherited = []; for (var i = 0; i < inheritedPayload.length; ++i) { var entryPayload = inheritedPayload[i]; var entry = {}; if (entryPayload.inlineStyle) entry.inlineStyle = WebInspector.CSSStyleDeclaration.parsePayload(entryPayload.inlineStyle); if (entryPayload.matchedCSSRules) entry.matchedCSSRules = WebInspector.CSSStyleModel.parseRuleMatchArrayPayload(entryPayload.matchedCSSRules); result.inherited.push(entry); } } if (userCallback) userCallback(result); } CSSAgent.getMatchedStylesForNode(nodeId, needPseudo, needInherited, callback.bind(null, userCallback)); }, getComputedStyleAsync: function(nodeId, userCallback) { function callback(userCallback, error, computedPayload) { if (error || !computedPayload) userCallback(null); else userCallback(WebInspector.CSSStyleDeclaration.parseComputedStylePayload(computedPayload)); } CSSAgent.getComputedStyleForNode(nodeId, callback.bind(null, userCallback)); }, getInlineStylesAsync: function(nodeId, userCallback) { function callback(userCallback, error, inlinePayload, attributesStylePayload) { if (error || !inlinePayload) userCallback(null, null); else userCallback(WebInspector.CSSStyleDeclaration.parsePayload(inlinePayload), attributesStylePayload ? WebInspector.CSSStyleDeclaration.parsePayload(attributesStylePayload) : null); } CSSAgent.getInlineStylesForNode(nodeId, callback.bind(null, userCallback)); }, forcePseudoState: function(nodeId, forcedPseudoClasses, userCallback) { CSSAgent.forcePseudoState(nodeId, forcedPseudoClasses || [], userCallback); }, getNamedFlowCollectionAsync: function(documentNodeId, userCallback) { var namedFlowCollection = this._namedFlowCollections[documentNodeId]; if (namedFlowCollection) { userCallback(namedFlowCollection); return; } function callback(userCallback, error, namedFlowPayload) { if (error || !namedFlowPayload) userCallback(null); else { var namedFlowCollection = new WebInspector.NamedFlowCollection(namedFlowPayload); this._namedFlowCollections[documentNodeId] = namedFlowCollection; userCallback(namedFlowCollection); } } CSSAgent.getNamedFlowCollection(documentNodeId, callback.bind(this, userCallback)); }, getFlowByNameAsync: function(documentNodeId, flowName, userCallback) { var namedFlowCollection = this._namedFlowCollections[documentNodeId]; if (namedFlowCollection) { userCallback(namedFlowCollection.flowByName(flowName)); return; } function callback(userCallback, namedFlowCollection) { if (!namedFlowCollection) userCallback(null); else userCallback(namedFlowCollection.flowByName(flowName)); } this.getNamedFlowCollectionAsync(documentNodeId, callback.bind(this, userCallback)); }, setRuleSelector: function(ruleId, nodeId, newSelector, successCallback, failureCallback) { function checkAffectsCallback(nodeId, successCallback, rulePayload, selectedNodeIds) { if (!selectedNodeIds) return; var doesAffectSelectedNode = (selectedNodeIds.indexOf(nodeId) >= 0); var rule = WebInspector.CSSRule.parsePayload(rulePayload); successCallback(rule, doesAffectSelectedNode); } function callback(nodeId, successCallback, failureCallback, newSelector, error, rulePayload) { this._pendingCommandsMajorState.pop(); if (error) failureCallback(); else { WebInspector.domAgent.markUndoableState(); var ownerDocumentId = this._ownerDocumentId(nodeId); if (ownerDocumentId) WebInspector.domAgent.querySelectorAll(ownerDocumentId, newSelector, checkAffectsCallback.bind(this, nodeId, successCallback, rulePayload)); else failureCallback(); } } this._pendingCommandsMajorState.push(true); CSSAgent.setRuleSelector(ruleId, newSelector, callback.bind(this, nodeId, successCallback, failureCallback, newSelector)); }, addRule: function(nodeId, selector, successCallback, failureCallback) { function checkAffectsCallback(nodeId, successCallback, rulePayload, selectedNodeIds) { if (!selectedNodeIds) return; var doesAffectSelectedNode = (selectedNodeIds.indexOf(nodeId) >= 0); var rule = WebInspector.CSSRule.parsePayload(rulePayload); successCallback(rule, doesAffectSelectedNode); } function callback(successCallback, failureCallback, selector, error, rulePayload) { this._pendingCommandsMajorState.pop(); if (error) { failureCallback(); } else { WebInspector.domAgent.markUndoableState(); var ownerDocumentId = this._ownerDocumentId(nodeId); if (ownerDocumentId) WebInspector.domAgent.querySelectorAll(ownerDocumentId, selector, checkAffectsCallback.bind(this, nodeId, successCallback, rulePayload)); else failureCallback(); } } this._pendingCommandsMajorState.push(true); CSSAgent.addRule(nodeId, selector, callback.bind(this, successCallback, failureCallback, selector)); }, mediaQueryResultChanged: function() { this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.MediaQueryResultChanged); }, _ownerDocumentId: function(nodeId) { var node = WebInspector.domAgent.nodeForId(nodeId); if (!node) return null; return node.ownerDocument ? node.ownerDocument.id : null; }, _fireStyleSheetChanged: function(styleSheetId) { if (!this._pendingCommandsMajorState.length) return; var majorChange = this._pendingCommandsMajorState[this._pendingCommandsMajorState.length - 1]; if (!majorChange || !styleSheetId || !this.hasEventListeners(WebInspector.CSSStyleModel.Events.StyleSheetChanged)) return; this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.StyleSheetChanged, { styleSheetId: styleSheetId, majorChange: majorChange }); }, _namedFlowCreated: function(namedFlowPayload) { var namedFlow = WebInspector.NamedFlow.parsePayload(namedFlowPayload); var namedFlowCollection = this._namedFlowCollections[namedFlow.documentNodeId]; if (!namedFlowCollection) return; namedFlowCollection._appendNamedFlow(namedFlow); this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.NamedFlowCreated, namedFlow); }, _namedFlowRemoved: function(documentNodeId, flowName) { var namedFlowCollection = this._namedFlowCollections[documentNodeId]; if (!namedFlowCollection) return; namedFlowCollection._removeNamedFlow(flowName); this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.NamedFlowRemoved, { documentNodeId: documentNodeId, flowName: flowName }); }, _regionLayoutUpdated: function(namedFlowPayload) { var namedFlow = WebInspector.NamedFlow.parsePayload(namedFlowPayload); var namedFlowCollection = this._namedFlowCollections[namedFlow.documentNodeId]; if (!namedFlowCollection) return; namedFlowCollection._appendNamedFlow(namedFlow); this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.RegionLayoutUpdated, namedFlow); }, setStyleSheetText: function(styleSheetId, newText, majorChange, userCallback) { function callback(error) { this._pendingCommandsMajorState.pop(); if (!error && majorChange) WebInspector.domAgent.markUndoableState(); if (!error && userCallback) userCallback(error); } this._pendingCommandsMajorState.push(majorChange); CSSAgent.setStyleSheetText(styleSheetId, newText, callback.bind(this)); }, _undoRedoRequested: function() { this._pendingCommandsMajorState.push(true); }, _undoRedoCompleted: function() { this._pendingCommandsMajorState.pop(); }, getViaInspectorResourceForRule: function(rule, callback) { if (!rule.id) { callback(null); return; } this._resourceBinding._requestViaInspectorResource(rule.id.styleSheetId, callback); }, resourceBinding: function() { return this._resourceBinding; }, setSourceMapping: function(url, sourceMapping) { this._sourceMappings[url] = sourceMapping; this._updateLocations(); }, resetSourceMappings: function() { this._sourceMappings = {}; }, _resetNamedFlowCollections: function() { this._namedFlowCollections = {}; }, _updateLocations: function() { for (var i = 0; i < this._locations.length; ++i) this._locations[i].update(); }, createLiveLocation: function(cssRule, updateDelegate) { if (!cssRule._rawLocation) return null; var location = new WebInspector.CSSStyleModel.LiveLocation(cssRule._rawLocation, updateDelegate); if (!location.uiLocation()) return null; this._locations.push(location); location.update(); return location; }, _rawLocationToUILocation: function(rawLocation) { var sourceMapping = this._sourceMappings[rawLocation.url]; return sourceMapping ? sourceMapping.rawLocationToUILocation(rawLocation) : null; }, __proto__: WebInspector.Object.prototype } WebInspector.CSSStyleModel.LiveLocation = function(rawLocation, updateDelegate) { WebInspector.LiveLocation.call(this, rawLocation, updateDelegate); } WebInspector.CSSStyleModel.LiveLocation.prototype = { uiLocation: function() { var cssLocation = (this.rawLocation()); return WebInspector.cssModel._rawLocationToUILocation(cssLocation); }, dispose: function() { WebInspector.LiveLocation.prototype.dispose.call(this); var locations = WebInspector.cssModel._locations; if (locations) locations.remove(this); }, __proto__: WebInspector.LiveLocation.prototype } WebInspector.CSSLocation = function(url, lineNumber) { this.url = url; this.lineNumber = lineNumber; } WebInspector.CSSStyleDeclaration = function(payload) { this.id = payload.styleId; this.width = payload.width; this.height = payload.height; this.range = payload.range; this._shorthandValues = WebInspector.CSSStyleDeclaration.buildShorthandValueMap(payload.shorthandEntries); this._livePropertyMap = {}; this._allProperties = []; this.__disabledProperties = {}; var payloadPropertyCount = payload.cssProperties.length; var propertyIndex = 0; for (var i = 0; i < payloadPropertyCount; ++i) { var property = WebInspector.CSSProperty.parsePayload(this, i, payload.cssProperties[i]); this._allProperties.push(property); if (property.disabled) this.__disabledProperties[i] = property; if (!property.active && !property.styleBased) continue; var name = property.name; this[propertyIndex] = name; this._livePropertyMap[name] = property; ++propertyIndex; } this.length = propertyIndex; if ("cssText" in payload) this.cssText = payload.cssText; } WebInspector.CSSStyleDeclaration.buildShorthandValueMap = function(shorthandEntries) { var result = {}; for (var i = 0; i < shorthandEntries.length; ++i) result[shorthandEntries[i].name] = shorthandEntries[i].value; return result; } WebInspector.CSSStyleDeclaration.parsePayload = function(payload) { return new WebInspector.CSSStyleDeclaration(payload); } WebInspector.CSSStyleDeclaration.parseComputedStylePayload = function(payload) { var newPayload = ({ cssProperties: [], shorthandEntries: [], width: "", height: "" }); if (payload) newPayload.cssProperties = payload; return new WebInspector.CSSStyleDeclaration(newPayload); } WebInspector.CSSStyleDeclaration.prototype = { get allProperties() { return this._allProperties; }, getLiveProperty: function(name) { return this._livePropertyMap[name]; }, getPropertyValue: function(name) { var property = this._livePropertyMap[name]; return property ? property.value : ""; }, getPropertyPriority: function(name) { var property = this._livePropertyMap[name]; return property ? property.priority : ""; }, isPropertyImplicit: function(name) { var property = this._livePropertyMap[name]; return property ? property.implicit : ""; }, longhandProperties: function(name) { var longhands = WebInspector.CSSCompletions.cssPropertiesMetainfo.longhands(name); var result = []; for (var i = 0; longhands && i < longhands.length; ++i) { var property = this._livePropertyMap[longhands[i]]; if (property) result.push(property); } return result; }, shorthandValue: function(shorthandProperty) { return this._shorthandValues[shorthandProperty]; }, propertyAt: function(index) { return (index < this.allProperties.length) ? this.allProperties[index] : null; }, pastLastSourcePropertyIndex: function() { for (var i = this.allProperties.length - 1; i >= 0; --i) { var property = this.allProperties[i]; if (property.active || property.disabled) return i + 1; } return 0; }, newBlankProperty: function(index) { index = (typeof index === "undefined") ? this.pastLastSourcePropertyIndex() : index; return new WebInspector.CSSProperty(this, index, "", "", "", "active", true, false, ""); }, insertPropertyAt: function(index, name, value, userCallback) { function callback(userCallback, error, payload) { WebInspector.cssModel._pendingCommandsMajorState.pop(); if (!userCallback) return; if (error) { console.error(error); userCallback(null); } else { userCallback(WebInspector.CSSStyleDeclaration.parsePayload(payload)); } } if (!this.id) throw "No style id"; WebInspector.cssModel._pendingCommandsMajorState.push(true); CSSAgent.setPropertyText(this.id, index, name + ": " + value + ";", false, callback.bind(this, userCallback)); }, appendProperty: function(name, value, userCallback) { this.insertPropertyAt(this.allProperties.length, name, value, userCallback); } } WebInspector.CSSRule = function(payload, matchingSelectors) { this.id = payload.ruleId; if (matchingSelectors) this.matchingSelectors = matchingSelectors; this.selectors = payload.selectorList.selectors; this.selectorText = payload.selectorList.text; this.selectorRange = payload.selectorList.range; this.sourceLine = payload.sourceLine; this.sourceURL = payload.sourceURL; if (payload.sourceURL) this._rawLocation = new WebInspector.CSSLocation(payload.sourceURL, payload.sourceLine); this.origin = payload.origin; this.style = WebInspector.CSSStyleDeclaration.parsePayload(payload.style); this.style.parentRule = this; if (payload.media) this.media = WebInspector.CSSMedia.parseMediaArrayPayload(payload.media); } WebInspector.CSSRule.parsePayload = function(payload, matchingIndices) { return new WebInspector.CSSRule(payload, matchingIndices); } WebInspector.CSSRule.prototype = { get isUserAgent() { return this.origin === "user-agent"; }, get isUser() { return this.origin === "user"; }, get isViaInspector() { return this.origin === "inspector"; }, get isRegular() { return this.origin === "regular"; } } WebInspector.CSSProperty = function(ownerStyle, index, name, value, priority, status, parsedOk, implicit, text) { this.ownerStyle = ownerStyle; this.index = index; this.name = name; this.value = value; this.priority = priority; this.status = status; this.parsedOk = parsedOk; this.implicit = implicit; this.text = text; } WebInspector.CSSProperty.parsePayload = function(ownerStyle, index, payload) { var result = new WebInspector.CSSProperty( ownerStyle, index, payload.name, payload.value, payload.priority || "", payload.status || "style", ("parsedOk" in payload) ? !!payload.parsedOk : true, !!payload.implicit, payload.text); return result; } WebInspector.CSSProperty.prototype = { get propertyText() { if (this.text !== undefined) return this.text; if (this.name === "") return ""; return this.name + ": " + this.value + (this.priority ? " !" + this.priority : "") + ";"; }, get isLive() { return this.active || this.styleBased; }, get active() { return this.status === "active"; }, get styleBased() { return this.status === "style"; }, get inactive() { return this.status === "inactive"; }, get disabled() { return this.status === "disabled"; }, setText: function(propertyText, majorChange, overwrite, userCallback) { function enabledCallback(style) { if (userCallback) userCallback(style); } function callback(error, stylePayload) { WebInspector.cssModel._pendingCommandsMajorState.pop(); if (!error) { if (majorChange) WebInspector.domAgent.markUndoableState(); this.text = propertyText; var style = WebInspector.CSSStyleDeclaration.parsePayload(stylePayload); var newProperty = style.allProperties[this.index]; if (newProperty && this.disabled && !propertyText.match(/^\s*$/)) { newProperty.setDisabled(false, enabledCallback); return; } if (userCallback) userCallback(style); } else { if (userCallback) userCallback(null); } } if (!this.ownerStyle) throw "No ownerStyle for property"; if (!this.ownerStyle.id) throw "No owner style id"; WebInspector.cssModel._pendingCommandsMajorState.push(majorChange); CSSAgent.setPropertyText(this.ownerStyle.id, this.index, propertyText, overwrite, callback.bind(this)); }, setValue: function(newValue, majorChange, overwrite, userCallback) { var text = this.name + ": " + newValue + (this.priority ? " !" + this.priority : "") + ";" this.setText(text, majorChange, overwrite, userCallback); }, setDisabled: function(disabled, userCallback) { if (!this.ownerStyle && userCallback) userCallback(null); if (disabled === this.disabled && userCallback) userCallback(this.ownerStyle); function callback(error, stylePayload) { WebInspector.cssModel._pendingCommandsMajorState.pop(); if (error) { if (userCallback) userCallback(null); return; } WebInspector.domAgent.markUndoableState(); if (userCallback) { var style = WebInspector.CSSStyleDeclaration.parsePayload(stylePayload); userCallback(style); } } if (!this.ownerStyle.id) throw "No owner style id"; WebInspector.cssModel._pendingCommandsMajorState.push(false); CSSAgent.toggleProperty(this.ownerStyle.id, this.index, disabled, callback.bind(this)); } } WebInspector.CSSMedia = function(payload) { this.text = payload.text; this.source = payload.source; this.sourceURL = payload.sourceURL || ""; this.sourceLine = typeof payload.sourceLine === "undefined" || this.source === "linkedSheet" ? -1 : payload.sourceLine; } WebInspector.CSSMedia.Source = { LINKED_SHEET: "linkedSheet", INLINE_SHEET: "inlineSheet", MEDIA_RULE: "mediaRule", IMPORT_RULE: "importRule" }; WebInspector.CSSMedia.parsePayload = function(payload) { return new WebInspector.CSSMedia(payload); } WebInspector.CSSMedia.parseMediaArrayPayload = function(payload) { var result = []; for (var i = 0; i < payload.length; ++i) result.push(WebInspector.CSSMedia.parsePayload(payload[i])); return result; } WebInspector.CSSStyleSheet = function(payload) { this.id = payload.styleSheetId; this.rules = []; this.styles = {}; for (var i = 0; i < payload.rules.length; ++i) { var rule = WebInspector.CSSRule.parsePayload(payload.rules[i]); this.rules.push(rule); if (rule.style) this.styles[rule.style.id] = rule.style; } if ("text" in payload) this._text = payload.text; } WebInspector.CSSStyleSheet.createForId = function(styleSheetId, userCallback) { function callback(error, styleSheetPayload) { if (error) userCallback(null); else userCallback(new WebInspector.CSSStyleSheet(styleSheetPayload)); } CSSAgent.getStyleSheet(styleSheetId, callback.bind(this)); } WebInspector.CSSStyleSheet.prototype = { getText: function() { return this._text; }, setText: function(newText, majorChange, userCallback) { function callback(error) { if (!error) WebInspector.domAgent.markUndoableState(); WebInspector.cssModel._pendingCommandsMajorState.pop(); if (userCallback) userCallback(error); } WebInspector.cssModel._pendingCommandsMajorState.push(majorChange); CSSAgent.setStyleSheetText(this.id, newText, callback.bind(this)); } } WebInspector.CSSStyleModelResourceBinding = function() { this._frameAndURLToStyleSheetId = {}; this._styleSheetIdToHeader = {}; WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged, this._inspectedURLChanged, this); } WebInspector.CSSStyleModelResourceBinding.prototype = { requestStyleSheetIdForResource: function(resource, callback) { function innerCallback() { callback(this._styleSheetIdForResource(resource)); } if (this._styleSheetIdForResource(resource)) innerCallback.call(this); else this._loadStyleSheetHeaders(innerCallback.bind(this)); }, requestResourceURLForStyleSheetId: function(styleSheetId, callback) { function innerCallback() { var header = this._styleSheetIdToHeader[styleSheetId]; if (!header) { callback(null); return; } var frame = WebInspector.resourceTreeModel.frameForId(header.frameId); if (!frame) { callback(null); return; } var styleSheetURL = header.origin === "inspector" ? this._viaInspectorResourceURL(header.sourceURL) : header.sourceURL; callback(styleSheetURL); } if (this._styleSheetIdToHeader[styleSheetId]) innerCallback.call(this); else this._loadStyleSheetHeaders(innerCallback.bind(this)); }, _styleSheetIdForResource: function(resource) { return this._frameAndURLToStyleSheetId[resource.frameId + ":" + resource.url]; }, _inspectedURLChanged: function(event) { this._frameAndURLToStyleSheetId = {}; this._styleSheetIdToHeader = {}; }, _loadStyleSheetHeaders: function(callback) { function didGetAllStyleSheets(error, infos) { if (error) { callback(error); return; } for (var i = 0; i < infos.length; ++i) { var info = infos[i]; if (info.origin === "inspector") { this._getOrCreateInspectorResource(info); continue; } this._frameAndURLToStyleSheetId[info.frameId + ":" + info.sourceURL] = info.styleSheetId; this._styleSheetIdToHeader[info.styleSheetId] = info; } callback(null); } CSSAgent.getAllStyleSheets(didGetAllStyleSheets.bind(this)); }, _requestViaInspectorResource: function(styleSheetId, callback) { var header = this._styleSheetIdToHeader[styleSheetId]; if (header) { callback(this._getOrCreateInspectorResource(header)); return; } function headersLoaded() { var header = this._styleSheetIdToHeader[styleSheetId]; if (header) callback(this._getOrCreateInspectorResource(header)); else callback(null); } this._loadStyleSheetHeaders(headersLoaded.bind(this)); }, _getOrCreateInspectorResource: function(header) { var frame = WebInspector.resourceTreeModel.frameForId(header.frameId); if (!frame) return null; var viaInspectorURL = this._viaInspectorResourceURL(header.sourceURL); var inspectorResource = frame.resourceForURL(viaInspectorURL); if (inspectorResource) return inspectorResource; var resource = frame.resourceForURL(header.sourceURL); if (!resource) return null; this._frameAndURLToStyleSheetId[header.frameId + ":" + viaInspectorURL] = header.styleSheetId; this._styleSheetIdToHeader[header.styleSheetId] = header; inspectorResource = new WebInspector.Resource(null, viaInspectorURL, resource.documentURL, resource.frameId, resource.loaderId, WebInspector.resourceTypes.Stylesheet, "text/css", true); function overrideRequestContent(callback) { function callbackWrapper(error, content) { callback(error ? "" : content, false, "text/css"); } CSSAgent.getStyleSheetText(header.styleSheetId, callbackWrapper); } inspectorResource.requestContent = overrideRequestContent; frame.addResource(inspectorResource); return inspectorResource; }, _viaInspectorResourceURL: function(documentURL) { var parsedURL = new WebInspector.ParsedURL(documentURL); var fakeURL = "inspector://" + parsedURL.host + parsedURL.folderPathComponents; if (!fakeURL.endsWith("/")) fakeURL += "/"; fakeURL += "inspector-stylesheet"; return fakeURL; } } WebInspector.CSSDispatcher = function(cssModel) { this._cssModel = cssModel; } WebInspector.CSSDispatcher.prototype = { mediaQueryResultChanged: function() { this._cssModel.mediaQueryResultChanged(); }, styleSheetChanged: function(styleSheetId) { this._cssModel._fireStyleSheetChanged(styleSheetId); }, namedFlowCreated: function(namedFlowPayload) { this._cssModel._namedFlowCreated(namedFlowPayload); }, namedFlowRemoved: function(documentNodeId, flowName) { this._cssModel._namedFlowRemoved(documentNodeId, flowName); }, regionLayoutUpdated: function(namedFlowPayload) { this._cssModel._regionLayoutUpdated(namedFlowPayload); } } WebInspector.NamedFlow = function(payload) { this.documentNodeId = payload.documentNodeId; this.name = payload.name; this.overset = payload.overset; this.content = payload.content; this.regions = payload.regions; } WebInspector.NamedFlow.parsePayload = function(payload) { return new WebInspector.NamedFlow(payload); } WebInspector.NamedFlowCollection = function(payload) { this.namedFlowMap = {}; for (var i = 0; i < payload.length; ++i) { var namedFlow = WebInspector.NamedFlow.parsePayload(payload[i]); this.namedFlowMap[namedFlow.name] = namedFlow; } } WebInspector.NamedFlowCollection.prototype = { _appendNamedFlow: function(namedFlow) { this.namedFlowMap[namedFlow.name] = namedFlow; }, _removeNamedFlow: function(flowName) { delete this.namedFlowMap[flowName]; }, flowByName: function(flowName) { var namedFlow = this.namedFlowMap[flowName]; if (!namedFlow) return null; return namedFlow; } } WebInspector.cssModel = null; WebInspector.NetworkManager = function() { WebInspector.Object.call(this); this._dispatcher = new WebInspector.NetworkDispatcher(this); if (WebInspector.settings.cacheDisabled.get()) NetworkAgent.setCacheDisabled(true); NetworkAgent.enable(); WebInspector.settings.cacheDisabled.addChangeListener(this._cacheDisabledSettingChanged, this); } WebInspector.NetworkManager.EventTypes = { RequestStarted: "RequestStarted", RequestUpdated: "RequestUpdated", RequestFinished: "RequestFinished", RequestUpdateDropped: "RequestUpdateDropped" } WebInspector.NetworkManager._MIMETypes = { "text/html": {"document": true}, "text/xml": {"document": true}, "text/plain": {"document": true}, "application/xhtml+xml": {"document": true}, "text/css": {"stylesheet": true}, "text/xsl": {"stylesheet": true}, "image/jpg": {"image": true}, "image/jpeg": {"image": true}, "image/pjpeg": {"image": true}, "image/png": {"image": true}, "image/gif": {"image": true}, "image/bmp": {"image": true}, "image/svg+xml": {"image": true}, "image/vnd.microsoft.icon": {"image": true}, "image/webp": {"image": true}, "image/x-icon": {"image": true}, "image/x-xbitmap": {"image": true}, "font/ttf": {"font": true}, "font/opentype": {"font": true}, "font/woff": {"font": true}, "application/x-font-type1": {"font": true}, "application/x-font-ttf": {"font": true}, "application/x-font-woff": {"font": true}, "application/x-truetype-font": {"font": true}, "text/javascript": {"script": true}, "text/ecmascript": {"script": true}, "application/javascript": {"script": true}, "application/ecmascript": {"script": true}, "application/x-javascript": {"script": true}, "application/json": {"script": true}, "text/javascript1.1": {"script": true}, "text/javascript1.2": {"script": true}, "text/javascript1.3": {"script": true}, "text/jscript": {"script": true}, "text/livescript": {"script": true}, } WebInspector.NetworkManager.prototype = { inflightRequestForURL: function(url) { return this._dispatcher._inflightRequestsByURL[url]; }, _cacheDisabledSettingChanged: function(event) { var enabled = (event.data); NetworkAgent.setCacheDisabled(enabled); }, __proto__: WebInspector.Object.prototype } WebInspector.NetworkDispatcher = function(manager) { this._manager = manager; this._inflightRequestsById = {}; this._inflightRequestsByURL = {}; InspectorBackend.registerNetworkDispatcher(this); } WebInspector.NetworkDispatcher.prototype = { _headersMapToHeadersArray: function(headersMap) { var result = []; for (var name in headersMap) { var values = headersMap[name].split("\n"); for (var i = 0; i < values.length; ++i) result.push({ name: name, value: values[i] }); } return result; }, _updateNetworkRequestWithRequest: function(networkRequest, request) { networkRequest.requestMethod = request.method; networkRequest.requestHeaders = this._headersMapToHeadersArray(request.headers); networkRequest.requestFormData = request.postData; }, _updateNetworkRequestWithResponse: function(networkRequest, response) { if (!response) return; if (response.url && networkRequest.url !== response.url) networkRequest.url = response.url; networkRequest.mimeType = response.mimeType; networkRequest.statusCode = response.status; networkRequest.statusText = response.statusText; networkRequest.responseHeaders = this._headersMapToHeadersArray(response.headers); if (response.headersText) networkRequest.responseHeadersText = response.headersText; if (response.requestHeaders) networkRequest.requestHeaders = this._headersMapToHeadersArray(response.requestHeaders); if (response.requestHeadersText) networkRequest.requestHeadersText = response.requestHeadersText; networkRequest.connectionReused = response.connectionReused; networkRequest.connectionId = response.connectionId; if (response.fromDiskCache) networkRequest.cached = true; else networkRequest.timing = response.timing; if (!this._mimeTypeIsConsistentWithType(networkRequest)) { WebInspector.console.addMessage(WebInspector.ConsoleMessage.create(WebInspector.ConsoleMessage.MessageSource.Network, WebInspector.ConsoleMessage.MessageLevel.Warning, WebInspector.UIString("Resource interpreted as %s but transferred with MIME type %s: \"%s\".", networkRequest.type.title(), networkRequest.mimeType, networkRequest.url), WebInspector.ConsoleMessage.MessageType.Log, "", 0, 1, [], null, networkRequest.requestId)); } }, _mimeTypeIsConsistentWithType: function(networkRequest) { if (networkRequest.hasErrorStatusCode() || networkRequest.statusCode === 304 || networkRequest.statusCode === 204) return true; if (typeof networkRequest.type === "undefined" || networkRequest.type === WebInspector.resourceTypes.Other || networkRequest.type === WebInspector.resourceTypes.XHR || networkRequest.type === WebInspector.resourceTypes.WebSocket) return true; if (!networkRequest.mimeType) return true; if (networkRequest.mimeType in WebInspector.NetworkManager._MIMETypes) return networkRequest.type.name() in WebInspector.NetworkManager._MIMETypes[networkRequest.mimeType]; return false; }, _updateNetworkRequestWithCachedResource: function(networkRequest, cachedResource) { networkRequest.type = WebInspector.resourceTypes[cachedResource.type]; networkRequest.resourceSize = cachedResource.bodySize; this._updateNetworkRequestWithResponse(networkRequest, cachedResource.response); }, _isNull: function(response) { if (!response) return true; return !response.status && !response.mimeType && (!response.headers || !Object.keys(response.headers).length); }, requestWillBeSent: function(requestId, frameId, loaderId, documentURL, request, time, initiator, redirectResponse) { var networkRequest = this._inflightRequestsById[requestId]; if (networkRequest) { if (!redirectResponse) return; this.responseReceived(requestId, frameId, loaderId, time, "Other", redirectResponse); networkRequest = this._appendRedirect(requestId, time, request.url); } else networkRequest = this._createNetworkRequest(requestId, frameId, loaderId, request.url, documentURL, initiator); networkRequest.hasNetworkData = true; this._updateNetworkRequestWithRequest(networkRequest, request); networkRequest.startTime = time; this._startNetworkRequest(networkRequest); }, requestServedFromCache: function(requestId) { var networkRequest = this._inflightRequestsById[requestId]; if (!networkRequest) return; networkRequest.cached = true; }, responseReceived: function(requestId, frameId, loaderId, time, resourceType, response) { if (this._isNull(response)) return; var networkRequest = this._inflightRequestsById[requestId]; if (!networkRequest) { var eventData = {}; eventData.url = response.url; eventData.frameId = frameId; eventData.loaderId = loaderId; eventData.resourceType = resourceType; eventData.mimeType = response.mimeType; this._manager.dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestUpdateDropped, eventData); return; } networkRequest.responseReceivedTime = time; networkRequest.type = WebInspector.resourceTypes[resourceType]; this._updateNetworkRequestWithResponse(networkRequest, response); this._updateNetworkRequest(networkRequest); }, dataReceived: function(requestId, time, dataLength, encodedDataLength) { var networkRequest = this._inflightRequestsById[requestId]; if (!networkRequest) return; networkRequest.resourceSize += dataLength; if (encodedDataLength != -1) networkRequest.increaseTransferSize(encodedDataLength); networkRequest.endTime = time; this._updateNetworkRequest(networkRequest); }, loadingFinished: function(requestId, finishTime) { var networkRequest = this._inflightRequestsById[requestId]; if (!networkRequest) return; this._finishNetworkRequest(networkRequest, finishTime); }, loadingFailed: function(requestId, time, localizedDescription, canceled) { var networkRequest = this._inflightRequestsById[requestId]; if (!networkRequest) return; networkRequest.failed = true; networkRequest.canceled = canceled; networkRequest.localizedFailDescription = localizedDescription; this._finishNetworkRequest(networkRequest, time); }, requestServedFromMemoryCache: function(requestId, frameId, loaderId, documentURL, time, initiator, cachedResource) { var networkRequest = this._createNetworkRequest(requestId, frameId, loaderId, cachedResource.url, documentURL, initiator); this._updateNetworkRequestWithCachedResource(networkRequest, cachedResource); networkRequest.cached = true; networkRequest.requestMethod = "GET"; this._startNetworkRequest(networkRequest); networkRequest.startTime = networkRequest.responseReceivedTime = time; this._finishNetworkRequest(networkRequest, time); }, webSocketCreated: function(requestId, requestURL) { var networkRequest = new WebInspector.NetworkRequest(requestId, requestURL, "", "", ""); networkRequest.type = WebInspector.resourceTypes.WebSocket; this._startNetworkRequest(networkRequest); }, webSocketWillSendHandshakeRequest: function(requestId, time, request) { var networkRequest = this._inflightRequestsById[requestId]; if (!networkRequest) return; networkRequest.requestMethod = "GET"; networkRequest.requestHeaders = this._headersMapToHeadersArray(request.headers); networkRequest.webSocketRequestKey3 = request.requestKey3; networkRequest.startTime = time; this._updateNetworkRequest(networkRequest); }, webSocketHandshakeResponseReceived: function(requestId, time, response) { var networkRequest = this._inflightRequestsById[requestId]; if (!networkRequest) return; networkRequest.statusCode = response.status; networkRequest.statusText = response.statusText; networkRequest.responseHeaders = this._headersMapToHeadersArray(response.headers); networkRequest.webSocketChallengeResponse = response.challengeResponse; networkRequest.responseReceivedTime = time; this._updateNetworkRequest(networkRequest); }, webSocketFrameReceived: function(requestId, time, response) { var networkRequest = this._inflightRequestsById[requestId]; if (!networkRequest) return; networkRequest.addFrame(response, time); networkRequest.responseReceivedTime = time; this._updateNetworkRequest(networkRequest); }, webSocketFrameSent: function(requestId, time, response) { var networkRequest = this._inflightRequestsById[requestId]; if (!networkRequest) return; networkRequest.addFrame(response, time, true); networkRequest.responseReceivedTime = time; this._updateNetworkRequest(networkRequest); }, webSocketFrameError: function(requestId, time, errorMessage) { var networkRequest = this._inflightRequestsById[requestId]; if (!networkRequest) return; networkRequest.addFrameError(errorMessage, time); networkRequest.responseReceivedTime = time; this._updateNetworkRequest(networkRequest); }, webSocketClosed: function(requestId, time) { var networkRequest = this._inflightRequestsById[requestId]; if (!networkRequest) return; this._finishNetworkRequest(networkRequest, time); }, _appendRedirect: function(requestId, time, redirectURL) { var originalNetworkRequest = this._inflightRequestsById[requestId]; var previousRedirects = originalNetworkRequest.redirects || []; originalNetworkRequest.requestId = "redirected:" + requestId + "." + previousRedirects.length; delete originalNetworkRequest.redirects; if (previousRedirects.length > 0) originalNetworkRequest.redirectSource = previousRedirects[previousRedirects.length - 1]; this._finishNetworkRequest(originalNetworkRequest, time); var newNetworkRequest = this._createNetworkRequest(requestId, originalNetworkRequest.frameId, originalNetworkRequest.loaderId, redirectURL, originalNetworkRequest.documentURL, originalNetworkRequest.initiator); newNetworkRequest.redirects = previousRedirects.concat(originalNetworkRequest); return newNetworkRequest; }, _startNetworkRequest: function(networkRequest) { this._inflightRequestsById[networkRequest.requestId] = networkRequest; this._inflightRequestsByURL[networkRequest.url] = networkRequest; this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestStarted, networkRequest); }, _updateNetworkRequest: function(networkRequest) { this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestUpdated, networkRequest); }, _finishNetworkRequest: function(networkRequest, finishTime) { networkRequest.endTime = finishTime; networkRequest.finished = true; this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestFinished, networkRequest); delete this._inflightRequestsById[networkRequest.requestId]; delete this._inflightRequestsByURL[networkRequest.url]; }, _dispatchEventToListeners: function(eventType, networkRequest) { this._manager.dispatchEventToListeners(eventType, networkRequest); }, _createNetworkRequest: function(requestId, frameId, loaderId, url, documentURL, initiator) { var networkRequest = new WebInspector.NetworkRequest(requestId, url, documentURL, frameId, loaderId); networkRequest.initiator = initiator; return networkRequest; } } WebInspector.networkManager = null; WebInspector.NetworkLog = function() { this._requests = []; this._requestForId = {}; WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestStarted, this._onRequestStarted, this); WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._onMainFrameNavigated, this); WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.OnLoad, this._onLoad, this); WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.DOMContentLoaded, this._onDOMContentLoaded, this); } WebInspector.NetworkLog.prototype = { get requests() { return this._requests; }, requestForURL: function(url) { for (var i = 0; i < this._requests.length; ++i) { if (this._requests[i].url === url) return this._requests[i]; } return null; }, pageLoadForRequest: function(request) { return request.__page; }, _onMainFrameNavigated: function(event) { var mainFrame = event.data; this._currentPageLoad = null; var oldRequests = this._requests.splice(0, this._requests.length); for (var i = 0; i < oldRequests.length; ++i) { var request = oldRequests[i]; if (request.loaderId === mainFrame.loaderId) { if (!this._currentPageLoad) this._currentPageLoad = new WebInspector.PageLoad(request); this._requests.push(request); request.__page = this._currentPageLoad; } } }, _onRequestStarted: function(event) { var request = (event.data); this._requests.push(request); this._requestForId[request.requestId] = request; request.__page = this._currentPageLoad; }, _onDOMContentLoaded: function(event) { if (this._currentPageLoad) this._currentPageLoad.contentLoadTime = event.data; }, _onLoad: function(event) { if (this._currentPageLoad) this._currentPageLoad.loadTime = event.data; }, requestForId: function(requestId) { return this._requestForId[requestId]; } } WebInspector.networkLog = null; WebInspector.PageLoad = function(mainRequest) { this.id = ++WebInspector.PageLoad._lastIdentifier; this.url = mainRequest.url; this.startTime = mainRequest.startTime; } WebInspector.PageLoad._lastIdentifier = 0; WebInspector.ResourceTreeModel = function(networkManager) { networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestFinished, this._onRequestFinished, this); networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestUpdateDropped, this._onRequestUpdateDropped, this); WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._consoleMessageAdded, this); WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.RepeatCountUpdated, this._consoleMessageAdded, this); WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this); PageAgent.enable(); NetworkAgent.enable(); this._fetchResourceTree(); InspectorBackend.registerPageDispatcher(new WebInspector.PageDispatcher(this)); this._pendingConsoleMessages = {}; } WebInspector.ResourceTreeModel.EventTypes = { FrameAdded: "FrameAdded", FrameNavigated: "FrameNavigated", FrameDetached: "FrameDetached", MainFrameNavigated: "MainFrameNavigated", ResourceAdded: "ResourceAdded", WillLoadCachedResources: "WillLoadCachedResources", CachedResourcesLoaded: "CachedResourcesLoaded", DOMContentLoaded: "DOMContentLoaded", OnLoad: "OnLoad", InspectedURLChanged: "InspectedURLChanged" } WebInspector.ResourceTreeModel.prototype = { _fetchResourceTree: function() { this._frames = {}; delete this._cachedResourcesProcessed; PageAgent.getResourceTree(this._processCachedResources.bind(this)); }, _processCachedResources: function(error, mainFramePayload) { if (error) { console.error(JSON.stringify(error)); return; } this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.WillLoadCachedResources); WebInspector.inspectedPageURL = mainFramePayload.frame.url; this._addFramesRecursively(null, mainFramePayload); this._dispatchInspectedURLChanged(); this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded); this._cachedResourcesProcessed = true; }, cachedResourcesLoaded: function() { return this._cachedResourcesProcessed; }, _dispatchInspectedURLChanged: function() { InspectorFrontendHost.inspectedURLChanged(WebInspector.inspectedPageURL); this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged, WebInspector.inspectedPageURL); }, _addFrame: function(frame) { this._frames[frame.id] = frame; if (frame.isMainFrame()) this.mainFrame = frame; this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameAdded, frame); }, _frameNavigated: function(framePayload) { if (!this._cachedResourcesProcessed) return; var frame = this._frames[framePayload.id]; if (frame) { frame._navigate(framePayload); } else { var parentFrame = this._frames[framePayload.parentId]; frame = new WebInspector.ResourceTreeFrame(this, parentFrame, framePayload); if (frame.isMainFrame() && this.mainFrame) { this._frameDetached(this.mainFrame.id); } this._addFrame(frame); } if (frame.isMainFrame()) WebInspector.inspectedPageURL = frame.url; this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, frame); if (frame.isMainFrame()) this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, frame); var resources = frame.resources(); for (var i = 0; i < resources.length; ++i) this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, resources[i]); if (frame.isMainFrame()) this._dispatchInspectedURLChanged(); }, _frameDetached: function(frameId) { if (!this._cachedResourcesProcessed) return; var frame = this._frames[frameId]; if (!frame) return; if (frame.parentFrame) frame.parentFrame._removeChildFrame(frame); else frame._remove(); }, _onRequestFinished: function(event) { if (!this._cachedResourcesProcessed) return; var request = (event.data); if (request.failed || request.type === WebInspector.resourceTypes.XHR) return; var frame = this._frames[request.frameId]; if (frame) { var resource = frame._addRequest(request); this._addPendingConsoleMessagesToResource(resource); } }, _onRequestUpdateDropped: function(event) { if (!this._cachedResourcesProcessed) return; var frameId = event.data.frameId; var frame = this._frames[frameId]; if (!frame) return; var url = event.data.url; if (frame._resourcesMap[url]) return; var resource = new WebInspector.Resource(null, url, frame.url, frameId, event.data.loaderId, WebInspector.resourceTypes[event.data.resourceType], event.data.mimeType); frame.addResource(resource); }, frameForId: function(frameId) { return this._frames[frameId]; }, forAllResources: function(callback) { if (this.mainFrame) return this.mainFrame._callForFrameResources(callback); return false; }, _consoleMessageAdded: function(event) { var msg = (event.data); var resource = msg.url ? this.resourceForURL(msg.url) : null; if (resource) this._addConsoleMessageToResource(msg, resource); else this._addPendingConsoleMessage(msg); }, _addPendingConsoleMessage: function(msg) { if (!msg.url) return; if (!this._pendingConsoleMessages[msg.url]) this._pendingConsoleMessages[msg.url] = []; this._pendingConsoleMessages[msg.url].push(msg); }, _addPendingConsoleMessagesToResource: function(resource) { var messages = this._pendingConsoleMessages[resource.url]; if (messages) { for (var i = 0; i < messages.length; i++) this._addConsoleMessageToResource(messages[i], resource); delete this._pendingConsoleMessages[resource.url]; } }, _addConsoleMessageToResource: function(msg, resource) { switch (msg.level) { case WebInspector.ConsoleMessage.MessageLevel.Warning: resource.warnings += msg.repeatDelta; break; case WebInspector.ConsoleMessage.MessageLevel.Error: resource.errors += msg.repeatDelta; break; } resource.addMessage(msg); }, _consoleCleared: function() { function callback(resource) { resource.clearErrorsAndWarnings(); } this._pendingConsoleMessages = {}; this.forAllResources(callback); }, resourceForURL: function(url) { return this.mainFrame ? this.mainFrame.resourceForURL(url) : null; }, _addFramesRecursively: function(parentFrame, frameTreePayload) { var framePayload = frameTreePayload.frame; var frame = new WebInspector.ResourceTreeFrame(this, parentFrame, framePayload); this._addFrame(frame); var frameResource = this._createResourceFromFramePayload(framePayload, framePayload.url, WebInspector.resourceTypes.Document, framePayload.mimeType); if (frame.isMainFrame()) WebInspector.inspectedPageURL = frameResource.url; frame.addResource(frameResource); for (var i = 0; frameTreePayload.childFrames && i < frameTreePayload.childFrames.length; ++i) this._addFramesRecursively(frame, frameTreePayload.childFrames[i]); for (var i = 0; i < frameTreePayload.resources.length; ++i) { var subresource = frameTreePayload.resources[i]; var resource = this._createResourceFromFramePayload(framePayload, subresource.url, WebInspector.resourceTypes[subresource.type], subresource.mimeType); frame.addResource(resource); } }, _createResourceFromFramePayload: function(frame, url, type, mimeType) { return new WebInspector.Resource(null, url, frame.url, frame.id, frame.loaderId, type, mimeType); }, __proto__: WebInspector.Object.prototype } WebInspector.ResourceTreeFrame = function(model, parentFrame, payload) { this._model = model; this._parentFrame = parentFrame; this._id = payload.id; this._loaderId = payload.loaderId; this._name = payload.name; this._url = payload.url; this._securityOrigin = payload.securityOrigin || ""; this._mimeType = payload.mimeType; this._childFrames = []; this._resourcesMap = {}; if (this._parentFrame) this._parentFrame._childFrames.push(this); } WebInspector.ResourceTreeFrame.prototype = { get id() { return this._id; }, get name() { return this._name || ""; }, get url() { return this._url; }, get securityOrigin() { return this._securityOrigin; }, get loaderId() { return this._loaderId; }, get parentFrame() { return this._parentFrame; }, get childFrames() { return this._childFrames; }, isMainFrame: function() { return !this._parentFrame; }, _navigate: function(framePayload) { this._loaderId = framePayload.loaderId; this._name = framePayload.name; this._url = framePayload.url; this._securityOrigin = framePayload.securityOrigin || ""; this._mimeType = framePayload.mimeType; var mainResource = this._resourcesMap[this._url]; this._resourcesMap = {}; this._removeChildFrames(); if (mainResource && mainResource.loaderId === this._loaderId) this.addResource(mainResource); }, get mainResource() { return this._resourcesMap[this._url]; }, _removeChildFrame: function(frame) { this._childFrames.remove(frame); frame._remove(); }, _removeChildFrames: function() { var copy = this._childFrames.slice(); for (var i = 0; i < copy.length; ++i) this._removeChildFrame(copy[i]); }, _remove: function() { this._removeChildFrames(); delete this._model._frames[this.id]; this._model.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this); }, addResource: function(resource) { if (this._resourcesMap[resource.url] === resource) { return; } this._resourcesMap[resource.url] = resource; this._model.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, resource); }, _addRequest: function(request) { var resource = this._resourcesMap[request.url]; if (resource && resource.request === request) { return resource; } resource = new WebInspector.Resource(request, request.url, request.documentURL, request.frameId, request.loaderId, request.type, request.mimeType); this._resourcesMap[resource.url] = resource; this._model.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, resource); return resource; }, resources: function() { var result = []; for (var url in this._resourcesMap) result.push(this._resourcesMap[url]); return result; }, resourceForURL: function(url) { var result; function filter(resource) { if (resource.url === url) { result = resource; return true; } } this._callForFrameResources(filter); return result; }, _callForFrameResources: function(callback) { for (var url in this._resourcesMap) { if (callback(this._resourcesMap[url])) return true; } for (var i = 0; i < this._childFrames.length; ++i) { if (this._childFrames[i]._callForFrameResources(callback)) return true; } return false; } } WebInspector.PageDispatcher = function(resourceTreeModel) { this._resourceTreeModel = resourceTreeModel; } WebInspector.PageDispatcher.prototype = { domContentEventFired: function(time) { this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.DOMContentLoaded, time); }, loadEventFired: function(time) { this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.OnLoad, time); }, frameNavigated: function(frame) { this._resourceTreeModel._frameNavigated(frame); }, frameDetached: function(frameId) { this._resourceTreeModel._frameDetached(frameId); } } WebInspector.resourceTreeModel = null; WebInspector.ParsedURL = function(url) { this.isValid = false; this.url = url; this.scheme = ""; this.host = ""; this.port = ""; this.path = ""; this.queryParams = ""; this.fragment = ""; this.folderPathComponents = ""; this.lastPathComponent = ""; var match = url.match(/^([A-Za-z][A-Za-z0-9+.-]*):\/\/([^\/:]*)(?::([\d]+))?(?:(\/[^#]*)(?:#(.*))?)?$/i); if (match) { this.isValid = true; this.scheme = match[1].toLowerCase(); this.host = match[2]; this.port = match[3]; this.path = match[4] || "/"; this.fragment = match[5]; } else { if (this.url.startsWith("data:")) { this.scheme = "data"; return; } if (this.url === "about:blank") { this.scheme = "about"; return; } this.path = this.url; } var path = this.path; var indexOfQuery = path.indexOf("?"); if (indexOfQuery !== -1) { this.queryParams = path.substring(indexOfQuery + 1) path = path.substring(0, indexOfQuery); } var lastSlashIndex = path.lastIndexOf("/"); if (lastSlashIndex !== -1) { this.folderPathComponents = path.substring(0, lastSlashIndex); this.lastPathComponent = path.substring(lastSlashIndex + 1); } else this.lastPathComponent = path; } WebInspector.ParsedURL.completeURL = function(baseURL, href) { if (href) { var trimmedHref = href.trim(); if (trimmedHref.startsWith("data:") || trimmedHref.startsWith("blob:") || trimmedHref.startsWith("javascript:")) return href; var parsedHref = trimmedHref.asParsedURL(); if (parsedHref && parsedHref.scheme) return trimmedHref; } else return baseURL; var parsedURL = baseURL.asParsedURL(); if (parsedURL) { var path = href; if (path.charAt(0) !== "/") { var basePath = parsedURL.path; var questionMarkIndex = basePath.indexOf("?"); if (questionMarkIndex > 0) basePath = basePath.substring(0, questionMarkIndex); var prefix; if (path.charAt(0) === "?") { var basePathCutIndex = basePath.indexOf("?"); if (basePathCutIndex !== -1) prefix = basePath.substring(0, basePathCutIndex); else prefix = basePath; } else prefix = basePath.substring(0, basePath.lastIndexOf("/")) + "/"; path = prefix + path; } else if (path.length > 1 && path.charAt(1) === "/") { return parsedURL.scheme + ":" + path; } return parsedURL.scheme + "://" + parsedURL.host + (parsedURL.port ? (":" + parsedURL.port) : "") + path; } return null; } WebInspector.ParsedURL.prototype = { get displayName() { if (this._displayName) return this._displayName; if (this.isDataURL()) return this.dataURLDisplayName(); if (this.isAboutBlank()) return this.url; this._displayName = this.lastPathComponent; if (!this._displayName) this._displayName = this.host; if (!this._displayName && this.url) this._displayName = this.url.trimURL(WebInspector.inspectedPageDomain ? WebInspector.inspectedPageDomain : ""); if (this._displayName === "/") this._displayName = this.url; return this._displayName; }, dataURLDisplayName: function() { if (this._dataURLDisplayName) return this._dataURLDisplayName; if (!this.isDataURL()) return ""; this._dataURLDisplayName = this.url.trimEnd(20); return this._dataURLDisplayName; }, isAboutBlank: function() { return this.url === "about:blank"; }, isDataURL: function() { return this.scheme === "data"; } } String.prototype.asParsedURL = function() { var parsedURL = new WebInspector.ParsedURL(this.toString()); if (parsedURL.isValid) return parsedURL; return null; } WebInspector.resourceForURL = function(url) { return WebInspector.resourceTreeModel.resourceForURL(url); } WebInspector.forAllResources = function(callback) { WebInspector.resourceTreeModel.forAllResources(callback); } WebInspector.displayNameForURL = function(url) { if (!url) return ""; var resource = WebInspector.resourceForURL(url); if (resource) return resource.displayName; var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(url); if (uiSourceCode) return uiSourceCode.parsedURL.displayName; if (!WebInspector.inspectedPageURL) return url.trimURL(""); var parsedURL = WebInspector.inspectedPageURL.asParsedURL(); var lastPathComponent = parsedURL ? parsedURL.lastPathComponent : parsedURL; var index = WebInspector.inspectedPageURL.indexOf(lastPathComponent); if (index !== -1 && index + lastPathComponent.length === WebInspector.inspectedPageURL.length) { var baseURL = WebInspector.inspectedPageURL.substring(0, index); if (url.startsWith(baseURL)) return url.substring(index); } return parsedURL ? url.trimURL(parsedURL.host) : url; } WebInspector.linkifyStringAsFragmentWithCustomLinkifier = function(string, linkifier) { var container = document.createDocumentFragment(); var linkStringRegEx = /(?:[a-zA-Z][a-zA-Z0-9+.-]{2,}:\/\/|data:|www\.)[\w$\-_+*'=\|\/\\(){}[\]%@~,:;.!?]{2,}[\w$\-_+*=\|\/\\({%@~]/; var lineColumnRegEx = /:(\d+)(:(\d+))?$/; while (string) { var linkString = linkStringRegEx.exec(string); if (!linkString) break; linkString = linkString[0]; var linkIndex = string.indexOf(linkString); var nonLink = string.substring(0, linkIndex); container.appendChild(document.createTextNode(nonLink)); var title = linkString; var realURL = (linkString.startsWith("www.") ? "http://" + linkString : linkString); var lineColumnMatch = lineColumnRegEx.exec(realURL); var lineNumber; if (lineColumnMatch) { realURL = realURL.substring(0, realURL.length - lineColumnMatch[0].length); lineNumber = parseInt(lineColumnMatch[1], 10); lineNumber = isNaN(lineNumber) ? undefined : lineNumber; } var linkNode = linkifier(title, realURL, lineNumber); container.appendChild(linkNode); string = string.substring(linkIndex + linkString.length, string.length); } if (string) container.appendChild(document.createTextNode(string)); return container; } WebInspector._linkifierPlugins = []; /** * @param {function(string):string} plugin */ WebInspector.registerLinkifierPlugin = function(plugin) { WebInspector._linkifierPlugins.push(plugin); } /** * @param {string} string * @return {DocumentFragment} */ WebInspector.linkifyStringAsFragment = function(string) { /** * @param {string} title * @param {string} url * @param {number=} lineNumber * @return {Node} */ function linkifier(title, url, lineNumber) { for (var i = 0; i < WebInspector._linkifierPlugins.length; ++i) title = WebInspector._linkifierPlugins[i](title); var isExternal = !WebInspector.resourceForURL(url); var urlNode = WebInspector.linkifyURLAsNode(url, title, undefined, isExternal); if (typeof(lineNumber) !== "undefined") { urlNode.lineNumber = lineNumber; urlNode.preferredPanel = "scripts"; } return urlNode; } return WebInspector.linkifyStringAsFragmentWithCustomLinkifier(string, linkifier); } /** * @param {string} url * @param {string=} linkText * @param {string=} classes * @param {boolean=} isExternal * @param {string=} tooltipText * @return {!Element} */ WebInspector.linkifyURLAsNode = function(url, linkText, classes, isExternal, tooltipText) { if (!linkText) linkText = url; classes = (classes ? classes + " " : ""); classes += isExternal ? "webkit-html-external-link" : "webkit-html-resource-link"; var a = document.createElement("a"); a.href = sanitizeHref(url); a.className = classes; if (typeof tooltipText === "undefined") a.title = url; else if (typeof tooltipText !== "string" || tooltipText.length) a.title = tooltipText; a.textContent = linkText.trimMiddle(150); if (isExternal) a.setAttribute("target", "_blank"); return a; } /** * @param {string} url * @param {number=} lineNumber * @return {string} */ WebInspector.formatLinkText = function(url, lineNumber) { var text = url ? WebInspector.displayNameForURL(url) : WebInspector.UIString("(program)"); if (typeof lineNumber === "number") text += ":" + (lineNumber + 1); return text; } /** * @param {string} url * @param {number=} lineNumber * @param {string=} classes * @param {string=} tooltipText * @return {Element} */ WebInspector.linkifyResourceAsNode = function(url, lineNumber, classes, tooltipText) { var linkText = WebInspector.formatLinkText(url, lineNumber); var anchor = WebInspector.linkifyURLAsNode(url, linkText, classes, false, tooltipText); anchor.preferredPanel = "resources"; anchor.lineNumber = lineNumber; return anchor; } /** * @param {WebInspector.NetworkRequest} request * @param {string=} classes * @return {Element} */ WebInspector.linkifyRequestAsNode = function(request, classes) { var anchor = WebInspector.linkifyURLAsNode(request.url); anchor.preferredPanel = "network"; anchor.requestId = request.requestId; return anchor; } /** * @param {string} content * @param {string} mimeType * @param {boolean} contentEncoded * @return {?string} */ WebInspector.contentAsDataURL = function(content, mimeType, contentEncoded) { const maxDataUrlSize = 1024 * 1024; if (content == null || content.length > maxDataUrlSize) return null; return "data:" + mimeType + (contentEncoded ? ";base64," : ",") + content; } /* ResourceType.js */ /* * Copyright (C) 2012 Google Inc. All rights reserved. * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @constructor * @param {string} name * @param {string} title * @param {string} categoryTitle * @param {string} color * @param {boolean} isTextType */ WebInspector.ResourceType = function(name, title, categoryTitle, color, isTextType) { this._name = name; this._title = title; this._categoryTitle = categoryTitle; this._color = color; this._isTextType = isTextType; } WebInspector.ResourceType.prototype = { /** * @return {string} */ name: function() { return this._name; }, /** * @return {string} */ title: function() { return this._title; }, /** * @return {string} */ categoryTitle: function() { return this._categoryTitle; }, /** * @return {string} */ color: function() { return this._color; }, /** * @return {boolean} */ isTextType: function() { return this._isTextType; }, /** * @return {string} */ toString: function() { return this._name; }, /** * @return {string} */ canonicalMimeType: function() { if (this === WebInspector.resourceTypes.Document) return "text/html"; if (this === WebInspector.resourceTypes.Script) return "text/javascript"; if (this === WebInspector.resourceTypes.Stylesheet) return "text/css"; return ""; } } /** * Keep these in sync with WebCore::InspectorPageAgent::resourceTypeJson * @enum {!WebInspector.ResourceType} */ WebInspector.resourceTypes = { Document: new WebInspector.ResourceType("document", "Document", "Documents", "rgb(47,102,236)", true), Stylesheet: new WebInspector.ResourceType("stylesheet", "Stylesheet", "Stylesheets", "rgb(157,231,119)", true), Image: new WebInspector.ResourceType("image", "Image", "Images", "rgb(164,60,255)", false), Script: new WebInspector.ResourceType("script", "Script", "Scripts", "rgb(255,121,0)", true), XHR: new WebInspector.ResourceType("xhr", "XHR", "XHR", "rgb(231,231,10)", true), Font: new WebInspector.ResourceType("font", "Font", "Fonts", "rgb(255,82,62)", false), WebSocket: new WebInspector.ResourceType("websocket", "WebSocket", "WebSockets", "rgb(186,186,186)", false), // FIXME: Decide the color. Other: new WebInspector.ResourceType("other", "Other", "Other", "rgb(186,186,186)", false) } /* TimelineManager.js */ /* * Copyright (C) 2011 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @constructor * @extends {WebInspector.Object} */ WebInspector.TimelineManager = function() { WebInspector.Object.call(this); this._dispatcher = new WebInspector.TimelineDispatcher(this); this._enablementCount = 0; } WebInspector.TimelineManager.EventTypes = { TimelineStarted: "TimelineStarted", TimelineStopped: "TimelineStopped", TimelineEventRecorded: "TimelineEventRecorded" } WebInspector.TimelineManager.prototype = { /** * @param {number=} maxCallStackDepth */ start: function(maxCallStackDepth) { this._enablementCount++; if (this._enablementCount === 1) TimelineAgent.start(maxCallStackDepth, this._started.bind(this)); }, stop: function() { if (!this._enablementCount) { console.error("WebInspector.TimelineManager start/stop calls are unbalanced"); return; } this._enablementCount--; if (!this._enablementCount) TimelineAgent.stop(this._stopped.bind(this)); }, _started: function() { this.dispatchEventToListeners(WebInspector.TimelineManager.EventTypes.TimelineStarted); }, _stopped: function() { this.dispatchEventToListeners(WebInspector.TimelineManager.EventTypes.TimelineStopped); }, __proto__: WebInspector.Object.prototype } /** * @constructor * @implements {TimelineAgent.Dispatcher} */ WebInspector.TimelineDispatcher = function(manager) { this._manager = manager; InspectorBackend.registerTimelineDispatcher(this); } WebInspector.TimelineDispatcher.prototype = { eventRecorded: function(record) { this._manager.dispatchEventToListeners(WebInspector.TimelineManager.EventTypes.TimelineEventRecorded, record); } } /** * @type {WebInspector.TimelineManager} */ WebInspector.timelineManager; /* UserAgentSupport.js */ /* * Copyright (C) 2012 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @constructor */ WebInspector.UserAgentSupport = function() { this._userAgentOverrideEnabled = false; this._deviceMetricsOverrideEnabled = false; this._geolocationPositionOverrideEnabled = false; this._deviceOrientationOverrideEnabled = false; WebInspector.settings.userAgent.addChangeListener(this._userAgentChanged, this); WebInspector.settings.deviceMetrics.addChangeListener(this._deviceMetricsChanged, this); WebInspector.settings.deviceFitWindow.addChangeListener(this._deviceMetricsChanged, this); WebInspector.settings.geolocationOverride.addChangeListener(this._geolocationPositionChanged, this); WebInspector.settings.deviceOrientationOverride.addChangeListener(this._deviceOrientationChanged, this); } /** * @constructor * @param {number} width * @param {number} height * @param {number} fontScaleFactor */ WebInspector.UserAgentSupport.DeviceMetrics = function(width, height, fontScaleFactor) { this.width = width; this.height = height; this.fontScaleFactor = fontScaleFactor; } /** * @return {WebInspector.UserAgentSupport.DeviceMetrics} */ WebInspector.UserAgentSupport.DeviceMetrics.parseSetting = function(value) { if (value) { var splitMetrics = value.split("x"); if (splitMetrics.length === 3) return new WebInspector.UserAgentSupport.DeviceMetrics(parseInt(splitMetrics[0], 10), parseInt(splitMetrics[1], 10), parseFloat(splitMetrics[2])); } return new WebInspector.UserAgentSupport.DeviceMetrics(0, 0, 1); } /** * @return {?WebInspector.UserAgentSupport.DeviceMetrics} */ WebInspector.UserAgentSupport.DeviceMetrics.parseUserInput = function(widthString, heightString, fontScaleFactorString) { function isUserInputValid(value, isInteger) { if (!value) return true; return isInteger ? /^[0]*[1-9][\d]*$/.test(value) : /^[0]*([1-9][\d]*(\.\d+)?|\.\d+)$/.test(value); } if (!widthString ^ !heightString) return null; var isWidthValid = isUserInputValid(widthString, true); var isHeightValid = isUserInputValid(heightString, true); var isFontScaleFactorValid = isUserInputValid(fontScaleFactorString, false); if (!isWidthValid && !isHeightValid && !isFontScaleFactorValid) return null; var width = isWidthValid ? parseInt(widthString || "0", 10) : -1; var height = isHeightValid ? parseInt(heightString || "0", 10) : -1; var fontScaleFactor = isFontScaleFactorValid ? parseFloat(fontScaleFactorString) : -1; return new WebInspector.UserAgentSupport.DeviceMetrics(width, height, fontScaleFactor); } WebInspector.UserAgentSupport.DeviceMetrics.prototype = { /** * @return {boolean} */ isValid: function() { return this.isWidthValid() && this.isHeightValid() && this.isFontScaleFactorValid(); }, /** * @return {boolean} */ isWidthValid: function() { return this.width >= 0; }, /** * @return {boolean} */ isHeightValid: function() { return this.height >= 0; }, /** * @return {boolean} */ isFontScaleFactorValid: function() { return this.fontScaleFactor > 0; }, /** * @return {string} */ toSetting: function() { if (!this.isValid()) return ""; return this.width && this.height ? this.width + "x" + this.height + "x" + this.fontScaleFactor : ""; }, /** * @return {string} */ widthToInput: function() { return this.isWidthValid() && this.width ? String(this.width) : ""; }, /** * @return {string} */ heightToInput: function() { return this.isHeightValid() && this.height ? String(this.height) : ""; }, /** * @return {string} */ fontScaleFactorToInput: function() { return this.isFontScaleFactorValid() && this.fontScaleFactor ? String(this.fontScaleFactor) : ""; } } /** * @constructor * @param {number} latitude * @param {number} longitude */ WebInspector.UserAgentSupport.GeolocationPosition = function(latitude, longitude, error) { this.latitude = latitude; this.longitude = longitude; this.error = error; } WebInspector.UserAgentSupport.GeolocationPosition.prototype = { /** * @return {string} */ toSetting: function() { return (typeof this.latitude === "number" && typeof this.longitude === "number" && typeof this.error === "string") ? this.latitude + "@" + this.longitude + ":" + this.error : ""; } } /** * @return {WebInspector.UserAgentSupport.GeolocationPosition} */ WebInspector.UserAgentSupport.GeolocationPosition.parseSetting = function(value) { if (value) { var splitError = value.split(":"); if (splitError.length === 2) { var splitPosition = splitError[0].split("@") if (splitPosition.length === 2) return new WebInspector.UserAgentSupport.GeolocationPosition(parseFloat(splitPosition[0]), parseFloat(splitPosition[1]), splitError[1]); } } return new WebInspector.UserAgentSupport.GeolocationPosition(0, 0, ""); } /** * @return {?WebInspector.UserAgentSupport.GeolocationPosition} */ WebInspector.UserAgentSupport.GeolocationPosition.parseUserInput = function(latitudeString, longitudeString, errorStatus) { function isUserInputValid(value) { if (!value) return true; return /^[-]?[0-9]*[.]?[0-9]*$/.test(value); } if (!latitudeString ^ !latitudeString) return null; var isLatitudeValid = isUserInputValid(latitudeString); var isLongitudeValid = isUserInputValid(longitudeString); if (!isLatitudeValid && !isLongitudeValid) return null; var latitude = isLatitudeValid ? parseFloat(latitudeString) : -1; var longitude = isLongitudeValid ? parseFloat(longitudeString) : -1; return new WebInspector.UserAgentSupport.GeolocationPosition(latitude, longitude, errorStatus ? "PositionUnavailable" : ""); } WebInspector.UserAgentSupport.GeolocationPosition.clearGeolocationOverride = function() { PageAgent.clearGeolocationOverride(); } /** * @constructor * @param {number} alpha * @param {number} beta * @param {number} gamma */ WebInspector.UserAgentSupport.DeviceOrientation = function(alpha, beta, gamma) { this.alpha = alpha; this.beta = beta; this.gamma = gamma; } WebInspector.UserAgentSupport.DeviceOrientation.prototype = { /** * @return {string} */ toSetting: function() { return JSON.stringify(this); } } /** * @return {WebInspector.UserAgentSupport.DeviceOrientation} */ WebInspector.UserAgentSupport.DeviceOrientation.parseSetting = function(value) { if (value) { var jsonObject = JSON.parse(value); return new WebInspector.UserAgentSupport.DeviceOrientation(jsonObject.alpha, jsonObject.beta, jsonObject.gamma); } return new WebInspector.UserAgentSupport.DeviceOrientation(0, 0, 0); } /** * @return {?WebInspector.UserAgentSupport.DeviceOrientation} */ WebInspector.UserAgentSupport.DeviceOrientation.parseUserInput = function(alphaString, betaString, gammaString) { function isUserInputValid(value) { if (!value) return true; return /^[-]?[0-9]*[.]?[0-9]*$/.test(value); } if (!alphaString ^ !betaString ^ !gammaString) return null; var isAlphaValid = isUserInputValid(alphaString); var isBetaValid = isUserInputValid(betaString); var isGammaValid = isUserInputValid(gammaString); if (!isAlphaValid && !isBetaValid && !isGammaValid) return null; var alpha = isAlphaValid ? parseFloat(alphaString) : -1; var beta = isBetaValid ? parseFloat(betaString) : -1; var gamma = isGammaValid ? parseFloat(gammaString) : -1; return new WebInspector.UserAgentSupport.DeviceOrientation(alpha, beta, gamma); } WebInspector.UserAgentSupport.DeviceOrientation.clearDeviceOrientationOverride = function() { PageAgent.clearDeviceOrientationOverride(); } WebInspector.UserAgentSupport.prototype = { toggleUserAgentOverride: function(enabled) { if (enabled === this._userAgentOverrideEnabled) return; this._userAgentOverrideEnabled = enabled; this._userAgentChanged(); }, toggleDeviceMetricsOverride: function(enabled) { if (enabled === this._deviceMetricsOverrideEnabled) return; this._deviceMetricsOverrideEnabled = enabled; this._deviceMetricsChanged(); }, toggleGeolocationPositionOverride: function(enabled) { if (enabled === this._geolocationPositionOverrideEnabled) return; this._geolocationPositionOverrideEnabled = enabled; this._geolocationPositionChanged(); }, toggleDeviceOrientationOverride: function(enabled) { if (enabled === this._deviceOrientationOverrideEnabled) return; this._deviceOrientationOverrideEnabled = enabled; this._deviceOrientationChanged(); }, _userAgentChanged: function() { NetworkAgent.setUserAgentOverride(this._userAgentOverrideEnabled ? WebInspector.settings.userAgent.get() : ""); }, _deviceMetricsChanged: function() { var metrics = WebInspector.UserAgentSupport.DeviceMetrics.parseSetting(this._deviceMetricsOverrideEnabled ? WebInspector.settings.deviceMetrics.get() : ""); if (metrics.isValid()) PageAgent.setDeviceMetricsOverride(metrics.width, metrics.height, metrics.fontScaleFactor, WebInspector.settings.deviceFitWindow.get()); }, _geolocationPositionChanged: function() { if (!this._geolocationPositionOverrideEnabled) { PageAgent.clearGeolocationOverride(); return; } var geolocation = WebInspector.UserAgentSupport.GeolocationPosition.parseSetting(WebInspector.settings.geolocationOverride.get()); if (geolocation.error) PageAgent.setGeolocationOverride(); else PageAgent.setGeolocationOverride(geolocation.latitude, geolocation.longitude, 150); }, _deviceOrientationChanged: function() { if (!this._deviceOrientationOverrideEnabled) { PageAgent.clearDeviceOrientationOverride(); return; } var deviceOrientation = WebInspector.UserAgentSupport.DeviceOrientation.parseSetting(WebInspector.settings.deviceOrientationOverride.get()); PageAgent.setDeviceOrientationOverride(deviceOrientation.alpha, deviceOrientation.beta, deviceOrientation.gamma); } } /** * @type {WebInspector.UserAgentSupport} */ WebInspector.userAgentSupport; /* Database.js */ /* * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @constructor * @param {WebInspector.DatabaseModel} model */ WebInspector.Database = function(model, id, domain, name, version) { this._model = model; this._id = id; this._domain = domain; this._name = name; this._version = version; } WebInspector.Database.prototype = { /** @return {string} */ get id() { return this._id; }, /** @return {string} */ get name() { return this._name; }, set name(x) { this._name = x; }, /** @return {string} */ get version() { return this._version; }, set version(x) { this._version = x; }, /** @return {string} */ get domain() { return this._domain; }, set domain(x) { this._domain = x; }, /** * @param {function(Array.<string>)} callback */ getTableNames: function(callback) { function sortingCallback(error, names) { if (!error) callback(names.sort()); } DatabaseAgent.getDatabaseTableNames(this._id, sortingCallback); }, /** * @param {string} query * @param {function(Array.<string>=, Array.<*>=)} onSuccess * @param {function(string)} onError */ executeSql: function(query, onSuccess, onError) { /** * @param {?Protocol.Error} error * @param {Array.<string>=} columnNames * @param {Array.<*>=} values * @param {DatabaseAgent.Error=} errorObj */ function callback(error, columnNames, values, errorObj) { if (error) { onError(error); return; } if (errorObj) { var message; if (errorObj.message) message = errorObj.message; else if (errorObj.code == 2) message = WebInspector.UIString("Database no longer has expected version."); else message = WebInspector.UIString("An unexpected error %s occurred.", errorObj.code); onError(message); return; } onSuccess(columnNames, values); } DatabaseAgent.executeSQL(this._id, query, callback.bind(this)); } } /** * @constructor * @extends {WebInspector.Object} */ WebInspector.DatabaseModel = function() { this._databases = []; InspectorBackend.registerDatabaseDispatcher(new WebInspector.DatabaseDispatcher(this)); DatabaseAgent.enable(); } WebInspector.DatabaseModel.Events = { DatabaseAdded: "DatabaseAdded" } WebInspector.DatabaseModel.prototype = { /** * @return {Array.<WebInspector.Database>} */ databases: function() { var result = []; for (var databaseId in this._databases) result.push(this._databases[databaseId]); return result; }, /** * @param {DatabaseAgent.DatabaseId} databaseId * @return {WebInspector.Database} */ databaseForId: function(databaseId) { return this._databases[databaseId]; }, /** * @param {WebInspector.Database} database */ _addDatabase: function(database) { this._databases.push(database); this.dispatchEventToListeners(WebInspector.DatabaseModel.Events.DatabaseAdded, database); }, __proto__: WebInspector.Object.prototype } /** * @constructor * @implements {DatabaseAgent.Dispatcher} * @param {WebInspector.DatabaseModel} model */ WebInspector.DatabaseDispatcher = function(model) { this._model = model; } WebInspector.DatabaseDispatcher.prototype = { /** * @param {DatabaseAgent.Database} payload */ addDatabase: function(payload) { this._model._addDatabase(new WebInspector.Database( this._model, payload.id, payload.domain, payload.name, payload.version)); } } /** * @type {WebInspector.DatabaseModel} */ WebInspector.databaseModel = null; /* DOMStorage.js */ /* * Copyright (C) 2008 Nokia Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @constructor */ WebInspector.DOMStorage = function(id, domain, isLocalStorage) { this._id = id; this._domain = domain; this._isLocalStorage = isLocalStorage; } WebInspector.DOMStorage.prototype = { /** @return {string} */ get id() { return this._id; }, /** @return {string} */ get domain() { return this._domain; }, /** @return {boolean} */ get isLocalStorage() { return this._isLocalStorage; }, /** * @param {function(?Protocol.Error, Array.<DOMStorageAgent.Entry>):void=} callback */ getEntries: function(callback) { DOMStorageAgent.getDOMStorageEntries(this._id, callback); }, /** * @param {string} key * @param {string} value * @param {function(?Protocol.Error, boolean):void=} callback */ setItem: function(key, value, callback) { DOMStorageAgent.setDOMStorageItem(this._id, key, value, callback); }, /** * @param {string} key * @param {function(?Protocol.Error, boolean):void=} callback */ removeItem: function(key, callback) { DOMStorageAgent.removeDOMStorageItem(this._id, key, callback); } } /** * @constructor * @extends {WebInspector.Object} */ WebInspector.DOMStorageModel = function() { this._storages = {}; InspectorBackend.registerDOMStorageDispatcher(new WebInspector.DOMStorageDispatcher(this)); DOMStorageAgent.enable(); } WebInspector.DOMStorageModel.Events = { DOMStorageAdded: "DOMStorageAdded", DOMStorageUpdated: "DOMStorageUpdated" } WebInspector.DOMStorageModel.prototype = { /** * @param {WebInspector.DOMStorage} domStorage */ _addDOMStorage: function(domStorage) { this._storages[domStorage.id] = domStorage; this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageAdded, domStorage); }, /** * @param {DOMStorageAgent.StorageId} storageId */ _domStorageUpdated: function(storageId) { this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageUpdated, this._storages[storageId]); }, /** * @param {DOMStorageAgent.StorageId} storageId * @return {WebInspector.DOMStorage} */ storageForId: function(storageId) { return this._storages[storageId]; }, /** * @return {Array.<WebInspector.DOMStorage>} */ storages: function() { var result = []; for (var storageId in this._storages) result.push(this._storages[storageId]); return result; }, __proto__: WebInspector.Object.prototype } /** * @constructor * @implements {DOMStorageAgent.Dispatcher} * @param {WebInspector.DOMStorageModel} model */ WebInspector.DOMStorageDispatcher = function(model) { this._model = model; } WebInspector.DOMStorageDispatcher.prototype = { /** * @param {DOMStorageAgent.Entry} payload */ addDOMStorage: function(payload) { this._model._addDOMStorage(new WebInspector.DOMStorage( payload.id, payload.origin, payload.isLocalStorage)); }, /** * @param {string} storageId */ domStorageUpdated: function(storageId) { this._model._domStorageUpdated(storageId); } } /** * @type {WebInspector.DOMStorageModel} */ WebInspector.domStorageModel = null; /* DataGrid.js */ /* * Copyright (C) 2008 Apple Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @constructor * @extends {WebInspector.View} * @param {function(WebInspector.DataGridNode, number, string, string)=} editCallback * @param {function(WebInspector.DataGridNode)=} deleteCallback */ WebInspector.DataGrid = function(columns, editCallback, deleteCallback) { WebInspector.View.call(this); this.registerRequiredCSS("dataGrid.css"); this.element.className = "data-grid"; this.element.tabIndex = 0; this.element.addEventListener("keydown", this._keyDown.bind(this), false); this._headerTable = document.createElement("table"); this._headerTable.className = "header"; this._headerTableHeaders = {}; this._dataTable = document.createElement("table"); this._dataTable.className = "data"; this._dataTable.addEventListener("mousedown", this._mouseDownInDataTable.bind(this), true); this._dataTable.addEventListener("click", this._clickInDataTable.bind(this), true); this._dataTable.addEventListener("contextmenu", this._contextMenuInDataTable.bind(this), true); // FIXME: Add a createCallback which is different from editCallback and has different // behavior when creating a new node. if (editCallback) { this._dataTable.addEventListener("dblclick", this._ondblclick.bind(this), false); this._editCallback = editCallback; } if (deleteCallback) this._deleteCallback = deleteCallback; this.aligned = {}; this._scrollContainer = document.createElement("div"); this._scrollContainer.className = "data-container"; this._scrollContainer.appendChild(this._dataTable); this.element.appendChild(this._headerTable); this.element.appendChild(this._scrollContainer); var headerRow = document.createElement("tr"); var columnGroup = document.createElement("colgroup"); this._columnCount = 0; for (var columnIdentifier in columns) { var column = columns[columnIdentifier]; if (column.disclosure) this.disclosureColumnIdentifier = columnIdentifier; var col = document.createElement("col"); if (column.width) col.style.width = column.width; column.element = col; columnGroup.appendChild(col); var cell = document.createElement("th"); cell.className = columnIdentifier + "-column"; cell.columnIdentifier = columnIdentifier; this._headerTableHeaders[columnIdentifier] = cell; var div = document.createElement("div"); if (column.titleDOMFragment) div.appendChild(column.titleDOMFragment); else div.textContent = column.title; cell.appendChild(div); if (column.sort) { cell.addStyleClass("sort-" + column.sort); this._sortColumnCell = cell; } if (column.sortable) { cell.addEventListener("click", this._clickInHeaderCell.bind(this), false); cell.addStyleClass("sortable"); } if (column.aligned) this.aligned[columnIdentifier] = column.aligned; headerRow.appendChild(cell); ++this._columnCount; } columnGroup.span = this._columnCount; var cell = document.createElement("th"); cell.className = "corner"; headerRow.appendChild(cell); this._headerTableColumnGroup = columnGroup; this._headerTable.appendChild(this._headerTableColumnGroup); this.headerTableBody.appendChild(headerRow); var fillerRow = document.createElement("tr"); fillerRow.className = "filler"; for (var columnIdentifier in columns) { var column = columns[columnIdentifier]; var td = document.createElement("td"); td.className = columnIdentifier + "-column"; fillerRow.appendChild(td); } this._dataTableColumnGroup = columnGroup.cloneNode(true); this._dataTable.appendChild(this._dataTableColumnGroup); this.dataTableBody.appendChild(fillerRow); this.columns = columns || {}; this._columnsArray = []; for (var columnIdentifier in columns) { columns[columnIdentifier].ordinal = this._columnsArray.length; columns[columnIdentifier].identifier = columnIdentifier; this._columnsArray.push(columns[columnIdentifier]); } for (var i = 0; i < this._columnsArray.length; ++i) this._columnsArray[i].bodyElement = this._dataTableColumnGroup.children[i]; this.selectedNode = null; this.expandNodesWhenArrowing = false; this.setRootNode(new WebInspector.DataGridNode()); this.indentWidth = 15; this.resizers = []; this._columnWidthsInitialized = false; } WebInspector.DataGrid.Events = { SelectedNode: "SelectedNode", DeselectedNode: "DeselectedNode" } /** * @param {Array.<string>} columnNames * @param {Array.<string>} values */ WebInspector.DataGrid.createSortableDataGrid = function(columnNames, values) { var numColumns = columnNames.length; if (!numColumns) return null; var columns = {}; for (var i = 0; i < columnNames.length; ++i) { var column = {}; column.width = columnNames[i].length; column.title = columnNames[i]; column.sortable = true; columns[columnNames[i]] = column; } var nodes = []; for (var i = 0; i < values.length / numColumns; ++i) { var data = {}; for (var j = 0; j < columnNames.length; ++j) data[columnNames[j]] = values[numColumns * i + j]; var node = new WebInspector.DataGridNode(data, false); node.selectable = false; nodes.push(node); } var dataGrid = new WebInspector.DataGrid(columns); var length = nodes.length; for (var i = 0; i < length; ++i) dataGrid.rootNode().appendChild(nodes[i]); dataGrid.addEventListener("sorting changed", sortDataGrid, this); function sortDataGrid() { var nodes = dataGrid._rootNode.children.slice(); var sortColumnIdentifier = dataGrid.sortColumnIdentifier; var sortDirection = dataGrid.sortOrder === "ascending" ? 1 : -1; var columnIsNumeric = true; for (var i = 0; i < nodes.length; i++) { if (isNaN(Number(nodes[i].data[sortColumnIdentifier]))) columnIsNumeric = false; } function comparator(dataGridNode1, dataGridNode2) { var item1 = dataGridNode1.data[sortColumnIdentifier]; var item2 = dataGridNode2.data[sortColumnIdentifier]; var comparison; if (columnIsNumeric) { // Sort numbers based on comparing their values rather than a lexicographical comparison. var number1 = parseFloat(item1); var number2 = parseFloat(item2); comparison = number1 < number2 ? -1 : (number1 > number2 ? 1 : 0); } else comparison = item1 < item2 ? -1 : (item1 > item2 ? 1 : 0); return sortDirection * comparison; } nodes.sort(comparator); dataGrid.rootNode().removeChildren(); for (var i = 0; i < nodes.length; i++) dataGrid._rootNode.appendChild(nodes[i]); } return dataGrid; } WebInspector.DataGrid.prototype = { setRootNode: function(rootNode) { if (this._rootNode) { this._rootNode.removeChildren(); this._rootNode.dataGrid = null; this._rootNode._isRoot = false; } this._rootNode = rootNode; rootNode._isRoot = true; rootNode.hasChildren = false; rootNode._expanded = true; rootNode._revealed = true; rootNode.dataGrid = this; }, rootNode: function() { return this._rootNode; }, get refreshCallback() { return this._refreshCallback; }, set refreshCallback(refreshCallback) { this._refreshCallback = refreshCallback; }, _ondblclick: function(event) { if (this._editing || this._editingNode) return; this._startEditing(event.target); }, _startEditingColumnOfDataGridNode: function(node, column) { this._editing = true; this._editingNode = node; this._editingNode.select(); var element = this._editingNode._element.children[column]; WebInspector.startEditing(element, this._startEditingConfig(element)); window.getSelection().setBaseAndExtent(element, 0, element, 1); }, _startEditing: function(target) { var element = target.enclosingNodeOrSelfWithNodeName("td"); if (!element) return; this._editingNode = this.dataGridNodeFromNode(target); if (!this._editingNode) { if (!this.creationNode) return; this._editingNode = this.creationNode; } // Force editing the 1st column when editing the creation node if (this._editingNode.isCreationNode) return this._startEditingColumnOfDataGridNode(this._editingNode, 0); this._editing = true; WebInspector.startEditing(element, this._startEditingConfig(element)); window.getSelection().setBaseAndExtent(element, 0, element, 1); }, _startEditingConfig: function(element) { return new WebInspector.EditingConfig(this._editingCommitted.bind(this), this._editingCancelled.bind(this), element.textContent); }, _editingCommitted: function(element, newText, oldText, context, moveDirection) { // FIXME: We need more column identifiers here throughout this function. // Not needed yet since only editable DataGrid is DOM Storage, which is Key - Value. // FIXME: Better way to do this than regular expressions? var columnIdentifier = parseInt(element.className.match(/\b(\d+)-column\b/)[1], 10); var textBeforeEditing = this._editingNode.data[columnIdentifier]; var currentEditingNode = this._editingNode; function moveToNextIfNeeded(wasChange) { if (!moveDirection) return; if (moveDirection === "forward") { if (currentEditingNode.isCreationNode && columnIdentifier === 0 && !wasChange) return; if (columnIdentifier === 0) return this._startEditingColumnOfDataGridNode(currentEditingNode, 1); var nextDataGridNode = currentEditingNode.traverseNextNode(true, null, true); if (nextDataGridNode) return this._startEditingColumnOfDataGridNode(nextDataGridNode, 0); if (currentEditingNode.isCreationNode && wasChange) { this.addCreationNode(false); return this._startEditingColumnOfDataGridNode(this.creationNode, 0); } return; } if (moveDirection === "backward") { if (columnIdentifier === 1) return this._startEditingColumnOfDataGridNode(currentEditingNode, 0); var nextDataGridNode = currentEditingNode.traversePreviousNode(true, null, true); if (nextDataGridNode) return this._startEditingColumnOfDataGridNode(nextDataGridNode, 1); return; } } if (textBeforeEditing == newText) { this._editingCancelled(element); moveToNextIfNeeded.call(this, false); return; } // Update the text in the datagrid that we typed this._editingNode.data[columnIdentifier] = newText; // Make the callback - expects an editing node (table row), the column number that is being edited, // the text that used to be there, and the new text. this._editCallback(this._editingNode, columnIdentifier, textBeforeEditing, newText); if (this._editingNode.isCreationNode) this.addCreationNode(false); this._editingCancelled(element); moveToNextIfNeeded.call(this, true); }, _editingCancelled: function(element) { delete this._editing; this._editingNode = null; }, /** * @return {?string} */ get sortColumnIdentifier() { if (!this._sortColumnCell) return null; return this._sortColumnCell.columnIdentifier; }, /** * @return {?string} */ get sortOrder() { if (!this._sortColumnCell || this._sortColumnCell.hasStyleClass("sort-ascending")) return "ascending"; if (this._sortColumnCell.hasStyleClass("sort-descending")) return "descending"; return null; }, get headerTableBody() { if ("_headerTableBody" in this) return this._headerTableBody; this._headerTableBody = this._headerTable.getElementsByTagName("tbody")[0]; if (!this._headerTableBody) { this._headerTableBody = this.element.ownerDocument.createElement("tbody"); this._headerTable.insertBefore(this._headerTableBody, this._headerTable.tFoot); } return this._headerTableBody; }, get dataTableBody() { if ("_dataTableBody" in this) return this._dataTableBody; this._dataTableBody = this._dataTable.getElementsByTagName("tbody")[0]; if (!this._dataTableBody) { this._dataTableBody = this.element.ownerDocument.createElement("tbody"); this._dataTable.insertBefore(this._dataTableBody, this._dataTable.tFoot); } return this._dataTableBody; }, /** * @param {Array.<number>} widths * @param {number} minPercent * @param {number=} maxPercent */ _autoSizeWidths: function(widths, minPercent, maxPercent) { if (minPercent) minPercent = Math.min(minPercent, Math.floor(100 / widths.length)); var totalWidth = 0; for (var i = 0; i < widths.length; ++i) totalWidth += widths[i]; var totalPercentWidth = 0; for (var i = 0; i < widths.length; ++i) { var width = Math.round(100 * widths[i] / totalWidth); if (minPercent && width < minPercent) width = minPercent; else if (maxPercent && width > maxPercent) width = maxPercent; totalPercentWidth += width; widths[i] = width; } var recoupPercent = totalPercentWidth - 100; while (minPercent && recoupPercent > 0) { for (var i = 0; i < widths.length; ++i) { if (widths[i] > minPercent) { --widths[i]; --recoupPercent; if (!recoupPercent) break; } } } while (maxPercent && recoupPercent < 0) { for (var i = 0; i < widths.length; ++i) { if (widths[i] < maxPercent) { ++widths[i]; ++recoupPercent; if (!recoupPercent) break; } } } return widths; }, /** * @param {number} minPercent * @param {number=} maxPercent * @param {number=} maxDescentLevel */ autoSizeColumns: function(minPercent, maxPercent, maxDescentLevel) { var widths = []; var columnIdentifiers = Object.keys(this.columns); for (var i = 0; i < columnIdentifiers.length; ++i) widths[i] = (this.columns[columnIdentifiers[i]].title || "").length; maxDescentLevel = maxDescentLevel || 0; var children = this._enumerateChildren(this._rootNode, [], maxDescentLevel + 1); for (var i = 0; i < children.length; ++i) { var node = children[i]; for (var j = 0; j < columnIdentifiers.length; ++j) { var text = node.data[columnIdentifiers[j]] || ""; if (text.length > widths[j]) widths[j] = text.length; } } widths = this._autoSizeWidths(widths, minPercent, maxPercent); for (var i = 0; i < columnIdentifiers.length; ++i) this.columns[columnIdentifiers[i]].element.style.width = widths[i] + "%"; this._columnWidthsInitialized = false; this.updateWidths(); }, _enumerateChildren: function(rootNode, result, maxLevel) { if (!rootNode._isRoot) result.push(rootNode); if (!maxLevel) return; for (var i = 0; i < rootNode.children.length; ++i) this._enumerateChildren(rootNode.children[i], result, maxLevel - 1); return result; }, onResize: function() { this.updateWidths(); }, // Updates the widths of the table, including the positions of the column // resizers. // // IMPORTANT: This function MUST be called once after the element of the // DataGrid is attached to its parent element and every subsequent time the // width of the parent element is changed in order to make it possible to // resize the columns. // // If this function is not called after the DataGrid is attached to its // parent element, then the DataGrid's columns will not be resizable. updateWidths: function() { var headerTableColumns = this._headerTableColumnGroup.children; var tableWidth = this._dataTable.offsetWidth; var numColumns = headerTableColumns.length; if (!this._columnWidthsInitialized && this.element.offsetWidth) { for (var i = 0; i < numColumns; i++) { var columnWidth = this.headerTableBody.rows[0].cells[i].offsetWidth; var percentWidth = ((columnWidth / tableWidth) * 100) + "%"; this._headerTableColumnGroup.children[i].style.width = percentWidth; this._dataTableColumnGroup.children[i].style.width = percentWidth; } this._columnWidthsInitialized = true; } this._positionResizers(); this.dispatchEventToListeners("width changed"); }, columnWidthsMap: function() { var result = {}; for (var i = 0; i < this._columnsArray.length; ++i) { var width = this._headerTableColumnGroup.children[i].style.width; result[this._columnsArray[i].columnIdentifier] = parseFloat(width); } return result; }, applyColumnWidthsMap: function(columnWidthsMap) { for (var columnIdentifier in this.columns) { var column = this.columns[columnIdentifier]; var width = (columnWidthsMap[columnIdentifier] || 0) + "%"; this._headerTableColumnGroup.children[column.ordinal].style.width = width; this._dataTableColumnGroup.children[column.ordinal].style.width = width; } delete this._columnWidthsInitialized; this.updateWidths(); }, isColumnVisible: function(columnIdentifier) { var column = this.columns[columnIdentifier]; var columnElement = column.element; return !columnElement.hidden; }, showColumn: function(columnIdentifier) { var column = this.columns[columnIdentifier]; var columnElement = column.element; if (!columnElement.hidden) return; columnElement.hidden = false; columnElement.removeStyleClass("hidden"); var columnBodyElement = column.bodyElement; columnBodyElement.hidden = false; columnBodyElement.removeStyleClass("hidden"); }, hideColumn: function(columnIdentifier) { var column = this.columns[columnIdentifier]; var columnElement = column.element; if (columnElement.hidden) return; var oldWidth = parseFloat(columnElement.style.width); columnElement.hidden = true; columnElement.addStyleClass("hidden"); columnElement.style.width = 0; var columnBodyElement = column.bodyElement; columnBodyElement.hidden = true; columnBodyElement.addStyleClass("hidden"); columnBodyElement.style.width = 0; this._columnWidthsInitialized = false; }, get scrollContainer() { return this._scrollContainer; }, isScrolledToLastRow: function() { return this._scrollContainer.isScrolledToBottom(); }, scrollToLastRow: function() { this._scrollContainer.scrollTop = this._scrollContainer.scrollHeight - this._scrollContainer.offsetHeight; }, _positionResizers: function() { var headerTableColumns = this._headerTableColumnGroup.children; var numColumns = headerTableColumns.length; var left = 0; var previousResizer = null; for (var i = 0; i < numColumns - 1; i++) { var resizer = this.resizers[i]; if (!resizer) { resizer = document.createElement("div"); resizer.addStyleClass("data-grid-resizer"); WebInspector.installDragHandle(resizer, this._startResizerDragging.bind(this), this._resizerDragging.bind(this), this._endResizerDragging.bind(this), "col-resize"); this.element.appendChild(resizer); this.resizers[i] = resizer; } left += this.headerTableBody.rows[0].cells[i].offsetWidth; var columnIsVisible = !this._headerTableColumnGroup.children[i].hidden; if (columnIsVisible) { resizer.style.removeProperty("display"); resizer.style.left = left + "px"; resizer.leftNeighboringColumnID = i; if (previousResizer) previousResizer.rightNeighboringColumnID = i; previousResizer = resizer; } else { resizer.style.setProperty("display", "none"); resizer.leftNeighboringColumnID = 0; resizer.rightNeighboringColumnID = 0; } } if (previousResizer) previousResizer.rightNeighboringColumnID = numColumns - 1; }, addCreationNode: function(hasChildren) { if (this.creationNode) this.creationNode.makeNormal(); var emptyData = {}; for (var column in this.columns) emptyData[column] = ''; this.creationNode = new WebInspector.CreationDataGridNode(emptyData, hasChildren); this.rootNode().appendChild(this.creationNode); }, sortNodes: function(comparator, reverseMode) { function comparatorWrapper(a, b) { if (a._dataGridNode._data.summaryRow) return 1; if (b._dataGridNode._data.summaryRow) return -1; var aDataGirdNode = a._dataGridNode; var bDataGirdNode = b._dataGridNode; return reverseMode ? comparator(bDataGirdNode, aDataGirdNode) : comparator(aDataGirdNode, bDataGirdNode); } var tbody = this.dataTableBody; var tbodyParent = tbody.parentElement; tbodyParent.removeChild(tbody); var childNodes = tbody.childNodes; var fillerRow = childNodes[childNodes.length - 1]; var sortedRows = Array.prototype.slice.call(childNodes, 0, childNodes.length - 1); sortedRows.sort(comparatorWrapper); var sortedRowsLength = sortedRows.length; tbody.removeChildren(); var previousSiblingNode = null; for (var i = 0; i < sortedRowsLength; ++i) { var row = sortedRows[i]; var node = row._dataGridNode; node.previousSibling = previousSiblingNode; if (previousSiblingNode) previousSiblingNode.nextSibling = node; tbody.appendChild(row); previousSiblingNode = node; } if (previousSiblingNode) previousSiblingNode.nextSibling = null; tbody.appendChild(fillerRow); tbodyParent.appendChild(tbody); }, _keyDown: function(event) { if (!this.selectedNode || event.shiftKey || event.metaKey || event.ctrlKey || this._editing) return; var handled = false; var nextSelectedNode; if (event.keyIdentifier === "Up" && !event.altKey) { nextSelectedNode = this.selectedNode.traversePreviousNode(true); while (nextSelectedNode && !nextSelectedNode.selectable) nextSelectedNode = nextSelectedNode.traversePreviousNode(true); handled = nextSelectedNode ? true : false; } else if (event.keyIdentifier === "Down" && !event.altKey) { nextSelectedNode = this.selectedNode.traverseNextNode(true); while (nextSelectedNode && !nextSelectedNode.selectable) nextSelectedNode = nextSelectedNode.traverseNextNode(true); handled = nextSelectedNode ? true : false; } else if (event.keyIdentifier === "Left") { if (this.selectedNode.expanded) { if (event.altKey) this.selectedNode.collapseRecursively(); else this.selectedNode.collapse(); handled = true; } else if (this.selectedNode.parent && !this.selectedNode.parent._isRoot) { handled = true; if (this.selectedNode.parent.selectable) { nextSelectedNode = this.selectedNode.parent; handled = nextSelectedNode ? true : false; } else if (this.selectedNode.parent) this.selectedNode.parent.collapse(); } } else if (event.keyIdentifier === "Right") { if (!this.selectedNode.revealed) { this.selectedNode.reveal(); handled = true; } else if (this.selectedNode.hasChildren) { handled = true; if (this.selectedNode.expanded) { nextSelectedNode = this.selectedNode.children[0]; handled = nextSelectedNode ? true : false; } else { if (event.altKey) this.selectedNode.expandRecursively(); else this.selectedNode.expand(); } } } else if (event.keyCode === 8 || event.keyCode === 46) { if (this._deleteCallback) { handled = true; this._deleteCallback(this.selectedNode); } } else if (isEnterKey(event)) { if (this._editCallback) { handled = true; this._startEditing(this.selectedNode._element.children[0]); } } if (nextSelectedNode) { nextSelectedNode.reveal(); nextSelectedNode.select(); } if (handled) event.consume(true); }, dataGridNodeFromNode: function(target) { var rowElement = target.enclosingNodeOrSelfWithNodeName("tr"); return rowElement && rowElement._dataGridNode; }, dataGridNodeFromPoint: function(x, y) { var node = this._dataTable.ownerDocument.elementFromPoint(x, y); var rowElement = node.enclosingNodeOrSelfWithNodeName("tr"); return rowElement && rowElement._dataGridNode; }, _clickInHeaderCell: function(event) { var cell = event.target.enclosingNodeOrSelfWithNodeName("th"); if (!cell || !cell.columnIdentifier || !cell.hasStyleClass("sortable")) return; var sortOrder = this.sortOrder; if (this._sortColumnCell) this._sortColumnCell.removeMatchingStyleClasses("sort-\\w+"); if (cell == this._sortColumnCell) { if (sortOrder === "ascending") sortOrder = "descending"; else sortOrder = "ascending"; } this._sortColumnCell = cell; cell.addStyleClass("sort-" + sortOrder); this.dispatchEventToListeners("sorting changed"); }, markColumnAsSortedBy: function(columnIdentifier, sortOrder) { if (this._sortColumnCell) this._sortColumnCell.removeMatchingStyleClasses("sort-\\w+"); this._sortColumnCell = this._headerTableHeaders[columnIdentifier]; this._sortColumnCell.addStyleClass("sort-" + sortOrder); }, headerTableHeader: function(columnIdentifier) { return this._headerTableHeaders[columnIdentifier]; }, _mouseDownInDataTable: function(event) { var gridNode = this.dataGridNodeFromNode(event.target); if (!gridNode || !gridNode.selectable) return; if (gridNode.isEventWithinDisclosureTriangle(event)) return; if (event.metaKey) { if (gridNode.selected) gridNode.deselect(); else gridNode.select(); } else gridNode.select(); }, _contextMenuInDataTable: function(event) { var contextMenu = new WebInspector.ContextMenu(event); var gridNode = this.dataGridNodeFromNode(event.target); if (this._refreshCallback && (!gridNode || gridNode !== this.creationNode)) contextMenu.appendItem(WebInspector.UIString("Refresh"), this._refreshCallback.bind(this)); if (gridNode && gridNode.selectable && !gridNode.isEventWithinDisclosureTriangle(event)) { if (this._editCallback) { if (gridNode === this.creationNode) contextMenu.appendItem(WebInspector.UIString("Add New"), this._startEditing.bind(this, event.target)); else contextMenu.appendItem(WebInspector.UIString("Edit"), this._startEditing.bind(this, event.target)); } if (this._deleteCallback && gridNode !== this.creationNode) contextMenu.appendItem(WebInspector.UIString("Delete"), this._deleteCallback.bind(this, gridNode)); } contextMenu.show(); }, _clickInDataTable: function(event) { var gridNode = this.dataGridNodeFromNode(event.target); if (!gridNode || !gridNode.hasChildren) return; if (!gridNode.isEventWithinDisclosureTriangle(event)) return; if (gridNode.expanded) { if (event.altKey) gridNode.collapseRecursively(); else gridNode.collapse(); } else { if (event.altKey) gridNode.expandRecursively(); else gridNode.expand(); } }, get resizeMethod() { if (typeof this._resizeMethod === "undefined") return WebInspector.DataGrid.ResizeMethod.Nearest; return this._resizeMethod; }, set resizeMethod(method) { this._resizeMethod = method; }, _startResizerDragging: function(event) { this._currentResizer = event.target; return !!this._currentResizer.rightNeighboringColumnID }, _resizerDragging: function(event) { var resizer = this._currentResizer; if (!resizer) return; var dragPoint = event.clientX - this.element.totalOffsetLeft(); var leftCellIndex = resizer.leftNeighboringColumnID; var rightCellIndex = resizer.rightNeighboringColumnID; var firstRowCells = this.headerTableBody.rows[0].cells; var leftEdgeOfPreviousColumn = 0; for (var i = 0; i < leftCellIndex; i++) leftEdgeOfPreviousColumn += firstRowCells[i].offsetWidth; if (this.resizeMethod == WebInspector.DataGrid.ResizeMethod.Last) { rightCellIndex = this.resizers.length; } else if (this.resizeMethod == WebInspector.DataGrid.ResizeMethod.First) { leftEdgeOfPreviousColumn += firstRowCells[leftCellIndex].offsetWidth - firstRowCells[0].offsetWidth; leftCellIndex = 0; } var rightEdgeOfNextColumn = leftEdgeOfPreviousColumn + firstRowCells[leftCellIndex].offsetWidth + firstRowCells[rightCellIndex].offsetWidth; var leftMinimum = leftEdgeOfPreviousColumn + this.ColumnResizePadding; var rightMaximum = rightEdgeOfNextColumn - this.ColumnResizePadding; dragPoint = Number.constrain(dragPoint, leftMinimum, rightMaximum); resizer.style.left = (dragPoint - this.CenterResizerOverBorderAdjustment) + "px"; var percentLeftColumn = (((dragPoint - leftEdgeOfPreviousColumn) / this._dataTable.offsetWidth) * 100) + "%"; this._headerTableColumnGroup.children[leftCellIndex].style.width = percentLeftColumn; this._dataTableColumnGroup.children[leftCellIndex].style.width = percentLeftColumn; var percentRightColumn = (((rightEdgeOfNextColumn - dragPoint) / this._dataTable.offsetWidth) * 100) + "%"; this._headerTableColumnGroup.children[rightCellIndex].style.width = percentRightColumn; this._dataTableColumnGroup.children[rightCellIndex].style.width = percentRightColumn; this._positionResizers(); event.preventDefault(); this.dispatchEventToListeners("width changed"); }, _endResizerDragging: function(event) { this._currentResizer = null; this.dispatchEventToListeners("width changed"); }, ColumnResizePadding: 10, CenterResizerOverBorderAdjustment: 3, __proto__: WebInspector.View.prototype } WebInspector.DataGrid.ResizeMethod = { Nearest: "nearest", First: "first", Last: "last" } WebInspector.DataGridNode = function(data, hasChildren) { this._expanded = false; this._selected = false; this._shouldRefreshChildren = true; this._data = data || {}; this.hasChildren = hasChildren || false; this.children = []; this.dataGrid = null; this.parent = null; this.previousSibling = null; this.nextSibling = null; this.disclosureToggleWidth = 10; } WebInspector.DataGridNode.prototype = { selectable: true, _isRoot: false, get element() { if (this._element) return this._element; if (!this.dataGrid) return null; this._element = document.createElement("tr"); this._element._dataGridNode = this; if (this.hasChildren) this._element.addStyleClass("parent"); if (this.expanded) this._element.addStyleClass("expanded"); if (this.selected) this._element.addStyleClass("selected"); if (this.revealed) this._element.addStyleClass("revealed"); this.createCells(); return this._element; }, createCells: function() { for (var columnIdentifier in this.dataGrid.columns) { var cell = this.createCell(columnIdentifier); this._element.appendChild(cell); } }, get data() { return this._data; }, set data(x) { this._data = x || {}; this.refresh(); }, get revealed() { if ("_revealed" in this) return this._revealed; var currentAncestor = this.parent; while (currentAncestor && !currentAncestor._isRoot) { if (!currentAncestor.expanded) { this._revealed = false; return false; } currentAncestor = currentAncestor.parent; } this._revealed = true; return true; }, set hasChildren(x) { if (this._hasChildren === x) return; this._hasChildren = x; if (!this._element) return; if (this._hasChildren) { this._element.addStyleClass("parent"); if (this.expanded) this._element.addStyleClass("expanded"); } else { this._element.removeStyleClass("parent"); this._element.removeStyleClass("expanded"); } }, get hasChildren() { return this._hasChildren; }, set revealed(x) { if (this._revealed === x) return; this._revealed = x; if (this._element) { if (this._revealed) this._element.addStyleClass("revealed"); else this._element.removeStyleClass("revealed"); } for (var i = 0; i < this.children.length; ++i) this.children[i].revealed = x && this.expanded; }, get depth() { if ("_depth" in this) return this._depth; if (this.parent && !this.parent._isRoot) this._depth = this.parent.depth + 1; else this._depth = 0; return this._depth; }, get leftPadding() { if (typeof(this._leftPadding) === "number") return this._leftPadding; this._leftPadding = this.depth * this.dataGrid.indentWidth; return this._leftPadding; }, get shouldRefreshChildren() { return this._shouldRefreshChildren; }, set shouldRefreshChildren(x) { this._shouldRefreshChildren = x; if (x && this.expanded) this.expand(); }, get selected() { return this._selected; }, set selected(x) { if (x) this.select(); else this.deselect(); }, get expanded() { return this._expanded; }, set expanded(x) { if (x) this.expand(); else this.collapse(); }, refresh: function() { if (!this._element || !this.dataGrid) return; this._element.removeChildren(); this.createCells(); }, createCell: function(columnIdentifier) { var cell = document.createElement("td"); cell.className = columnIdentifier + "-column"; var alignment = this.dataGrid.aligned[columnIdentifier]; if (alignment) cell.addStyleClass(alignment); var data = this.data[columnIdentifier]; var div = document.createElement("div"); if (data instanceof Node) div.appendChild(data); else div.textContent = data; cell.appendChild(div); if (columnIdentifier === this.dataGrid.disclosureColumnIdentifier) { cell.addStyleClass("disclosure"); if (this.leftPadding) cell.style.setProperty("padding-left", this.leftPadding + "px"); } return cell; }, nodeHeight: function() { var rowHeight = 16; if (!this.revealed) return 0; if (!this.expanded) return rowHeight; var result = rowHeight; for (var i = 0; i < this.children.length; i++) result += this.children[i].nodeHeight(); return result; }, appendChild: function(child) { this.insertChild(child, this.children.length); }, insertChild: function(child, index) { if (!child) throw("insertChild: Node can't be undefined or null."); if (child.parent === this) throw("insertChild: Node is already a child of this node."); if (child.parent) child.parent.removeChild(child); this.children.splice(index, 0, child); this.hasChildren = true; child.parent = this; child.dataGrid = this.dataGrid; child._recalculateSiblings(index); delete child._depth; delete child._revealed; delete child._attached; child._shouldRefreshChildren = true; var current = child.children[0]; while (current) { current.dataGrid = this.dataGrid; delete current._depth; delete current._revealed; delete current._attached; current._shouldRefreshChildren = true; current = current.traverseNextNode(false, child, true); } if (this.expanded) child._attach(); if (!this.revealed) child.revealed = false; }, removeChild: function(child) { if (!child) throw("removeChild: Node can't be undefined or null."); if (child.parent !== this) throw("removeChild: Node is not a child of this node."); child.deselect(); child._detach(); this.children.remove(child, true); if (child.previousSibling) child.previousSibling.nextSibling = child.nextSibling; if (child.nextSibling) child.nextSibling.previousSibling = child.previousSibling; child.dataGrid = null; child.parent = null; child.nextSibling = null; child.previousSibling = null; if (this.children.length <= 0) this.hasChildren = false; }, removeChildren: function() { for (var i = 0; i < this.children.length; ++i) { var child = this.children[i]; child.deselect(); child._detach(); child.dataGrid = null; child.parent = null; child.nextSibling = null; child.previousSibling = null; } this.children = []; this.hasChildren = false; }, _recalculateSiblings: function(myIndex) { if (!this.parent) return; var previousChild = (myIndex > 0 ? this.parent.children[myIndex - 1] : null); if (previousChild) { previousChild.nextSibling = this; this.previousSibling = previousChild; } else this.previousSibling = null; var nextChild = this.parent.children[myIndex + 1]; if (nextChild) { nextChild.previousSibling = this; this.nextSibling = nextChild; } else this.nextSibling = null; }, collapse: function() { if (this._isRoot) return; if (this._element) this._element.removeStyleClass("expanded"); this._expanded = false; for (var i = 0; i < this.children.length; ++i) this.children[i].revealed = false; this.dispatchEventToListeners("collapsed"); }, collapseRecursively: function() { var item = this; while (item) { if (item.expanded) item.collapse(); item = item.traverseNextNode(false, this, true); } }, expand: function() { if (!this.hasChildren || this.expanded) return; if (this._isRoot) return; if (this.revealed && !this._shouldRefreshChildren) for (var i = 0; i < this.children.length; ++i) this.children[i].revealed = true; if (this._shouldRefreshChildren) { for (var i = 0; i < this.children.length; ++i) this.children[i]._detach(); this.dispatchEventToListeners("populate"); if (this._attached) { for (var i = 0; i < this.children.length; ++i) { var child = this.children[i]; if (this.revealed) child.revealed = true; child._attach(); } } delete this._shouldRefreshChildren; } if (this._element) this._element.addStyleClass("expanded"); this._expanded = true; this.dispatchEventToListeners("expanded"); }, expandRecursively: function() { var item = this; while (item) { item.expand(); item = item.traverseNextNode(false, this); } }, reveal: function() { if (this._isRoot) return; var currentAncestor = this.parent; while (currentAncestor && !currentAncestor._isRoot) { if (!currentAncestor.expanded) currentAncestor.expand(); currentAncestor = currentAncestor.parent; } this.element.scrollIntoViewIfNeeded(false); this.dispatchEventToListeners("revealed"); }, select: function(supressSelectedEvent) { if (!this.dataGrid || !this.selectable || this.selected) return; if (this.dataGrid.selectedNode) this.dataGrid.selectedNode.deselect(); this._selected = true; this.dataGrid.selectedNode = this; if (this._element) this._element.addStyleClass("selected"); if (!supressSelectedEvent) { this.dispatchEventToListeners("selected"); this.dataGrid.dispatchEventToListeners(WebInspector.DataGrid.Events.SelectedNode); } }, revealAndSelect: function() { if (this._isRoot) return; this.reveal(); this.select(); }, deselect: function(supressDeselectedEvent) { if (!this.dataGrid || this.dataGrid.selectedNode !== this || !this.selected) return; this._selected = false; this.dataGrid.selectedNode = null; if (this._element) this._element.removeStyleClass("selected"); if (!supressDeselectedEvent) { this.dispatchEventToListeners("deselected"); this.dataGrid.dispatchEventToListeners(WebInspector.DataGrid.Events.DeselectedNode); } }, traverseNextNode: function(skipHidden, stayWithin, dontPopulate, info) { if (!dontPopulate && this.hasChildren) this.dispatchEventToListeners("populate"); if (info) info.depthChange = 0; var node = (!skipHidden || this.revealed) ? this.children[0] : null; if (node && (!skipHidden || this.expanded)) { if (info) info.depthChange = 1; return node; } if (this === stayWithin) return null; node = (!skipHidden || this.revealed) ? this.nextSibling : null; if (node) return node; node = this; while (node && !node._isRoot && !((!skipHidden || node.revealed) ? node.nextSibling : null) && node.parent !== stayWithin) { if (info) info.depthChange -= 1; node = node.parent; } if (!node) return null; return (!skipHidden || node.revealed) ? node.nextSibling : null; }, traversePreviousNode: function(skipHidden, dontPopulate) { var node = (!skipHidden || this.revealed) ? this.previousSibling : null; if (!dontPopulate && node && node.hasChildren) node.dispatchEventToListeners("populate"); while (node && ((!skipHidden || (node.revealed && node.expanded)) ? node.children[node.children.length - 1] : null)) { if (!dontPopulate && node.hasChildren) node.dispatchEventToListeners("populate"); node = ((!skipHidden || (node.revealed && node.expanded)) ? node.children[node.children.length - 1] : null); } if (node) return node; if (!this.parent || this.parent._isRoot) return null; return this.parent; }, isEventWithinDisclosureTriangle: function(event) { if (!this.hasChildren) return false; var cell = event.target.enclosingNodeOrSelfWithNodeName("td"); if (!cell.hasStyleClass("disclosure")) return false; var left = cell.totalOffsetLeft() + this.leftPadding; return event.pageX >= left && event.pageX <= left + this.disclosureToggleWidth; }, _attach: function() { if (!this.dataGrid || this._attached) return; this._attached = true; var nextNode = null; var previousNode = this.traversePreviousNode(true, true); if (previousNode && previousNode.element.parentNode && previousNode.element.nextSibling) nextNode = previousNode.element.nextSibling; if (!nextNode) nextNode = this.dataGrid.dataTableBody.firstChild; this.dataGrid.dataTableBody.insertBefore(this.element, nextNode); if (this.expanded) for (var i = 0; i < this.children.length; ++i) this.children[i]._attach(); }, _detach: function() { if (!this._attached) return; this._attached = false; if (this._element && this._element.parentNode) this._element.parentNode.removeChild(this._element); for (var i = 0; i < this.children.length; ++i) this.children[i]._detach(); this.wasDetached(); }, wasDetached: function() { }, savePosition: function() { if (this._savedPosition) return; if (!this.parent) throw("savePosition: Node must have a parent."); this._savedPosition = { parent: this.parent, index: this.parent.children.indexOf(this) }; }, restorePosition: function() { if (!this._savedPosition) return; if (this.parent !== this._savedPosition.parent) this._savedPosition.parent.insertChild(this, this._savedPosition.index); delete this._savedPosition; }, __proto__: WebInspector.Object.prototype } WebInspector.CreationDataGridNode = function(data, hasChildren) { WebInspector.DataGridNode.call(this, data, hasChildren); this.isCreationNode = true; } WebInspector.CreationDataGridNode.prototype = { makeNormal: function() { delete this.isCreationNode; delete this.makeNormal; }, __proto__: WebInspector.DataGridNode.prototype } WebInspector.ShowMoreDataGridNode = function(callback, startPosition, endPosition, chunkSize) { WebInspector.DataGridNode.call(this, {summaryRow:true}, false); this._callback = callback; this._startPosition = startPosition; this._endPosition = endPosition; this._chunkSize = chunkSize; this.showNext = document.createElement("button"); this.showNext.setAttribute("type", "button"); this.showNext.addEventListener("click", this._showNextChunk.bind(this), false); this.showNext.textContent = WebInspector.UIString("Show %d before", this._chunkSize); this.showAll = document.createElement("button"); this.showAll.setAttribute("type", "button"); this.showAll.addEventListener("click", this._showAll.bind(this), false); this.showLast = document.createElement("button"); this.showLast.setAttribute("type", "button"); this.showLast.addEventListener("click", this._showLastChunk.bind(this), false); this.showLast.textContent = WebInspector.UIString("Show %d after", this._chunkSize); this._updateLabels(); this.selectable = false; } WebInspector.ShowMoreDataGridNode.prototype = { _showNextChunk: function() { this._callback(this._startPosition, this._startPosition + this._chunkSize); }, _showAll: function() { this._callback(this._startPosition, this._endPosition); }, _showLastChunk: function() { this._callback(this._endPosition - this._chunkSize, this._endPosition); }, _updateLabels: function() { var totalSize = this._endPosition - this._startPosition; if (totalSize > this._chunkSize) { this.showNext.removeStyleClass("hidden"); this.showLast.removeStyleClass("hidden"); } else { this.showNext.addStyleClass("hidden"); this.showLast.addStyleClass("hidden"); } this.showAll.textContent = WebInspector.UIString("Show all %d", totalSize); }, createCells: function() { var cell = document.createElement("td"); if (this.depth) cell.style.setProperty("padding-left", (this.depth * this.dataGrid.indentWidth) + "px"); cell.appendChild(this.showNext); cell.appendChild(this.showAll); cell.appendChild(this.showLast); this._element.appendChild(cell); var columns = this.dataGrid.columns; var count = 0; for (var c in columns) ++count; while (--count > 0) { cell = document.createElement("td"); this._element.appendChild(cell); } }, setStartPosition: function(from) { this._startPosition = from; this._updateLabels(); }, setEndPosition: function(to) { this._endPosition = to; this._updateLabels(); }, nodeHeight: function() { return 32; }, dispose: function() { }, __proto__: WebInspector.DataGridNode.prototype } WebInspector.CookiesTable = function(cookieDomain, expandable, deleteCallback, refreshCallback) { WebInspector.View.call(this); this.element.className = "fill"; this._cookieDomain = cookieDomain; var columns = { 0: {}, 1: {}, 2: {}, 3: {}, 4: {}, 5: {}, 6: {}, 7: {} }; columns[0].title = WebInspector.UIString("Name"); columns[0].sortable = true; columns[0].disclosure = expandable; columns[0].width = "24%"; columns[1].title = WebInspector.UIString("Value"); columns[1].sortable = true; columns[1].width = "34%"; columns[2].title = WebInspector.UIString("Domain"); columns[2].sortable = true; columns[2].width = "7%"; columns[3].title = WebInspector.UIString("Path"); columns[3].sortable = true; columns[3].width = "7%"; columns[4].title = WebInspector.UIString("Expires / Max-Age"); columns[4].sortable = true; columns[4].width = "7%"; columns[5].title = WebInspector.UIString("Size"); columns[5].aligned = "right"; columns[5].sortable = true; columns[5].width = "7%"; columns[6].title = WebInspector.UIString("HTTP"); columns[6].aligned = "centered"; columns[6].sortable = true; columns[6].width = "7%"; columns[7].title = WebInspector.UIString("Secure"); columns[7].aligned = "centered"; columns[7].sortable = true; columns[7].width = "7%"; this._dataGrid = new WebInspector.DataGrid(columns, undefined, deleteCallback ? this._onDeleteFromGrid.bind(this, deleteCallback) : undefined); this._dataGrid.addEventListener("sorting changed", this._rebuildTable, this); this._dataGrid.refreshCallback = refreshCallback; this._dataGrid.show(this.element); this._data = []; } WebInspector.CookiesTable.prototype = { updateWidths: function() { if (this._dataGrid) this._dataGrid.updateWidths(); }, setCookies: function(cookies) { this._data = [{cookies: cookies}]; this._rebuildTable(); }, addCookiesFolder: function(folderName, cookies) { this._data.push({cookies: cookies, folderName: folderName}); this._rebuildTable(); }, get selectedCookie() { var node = this._dataGrid.selectedNode; return node ? node.cookie : null; }, _rebuildTable: function() { this._dataGrid.rootNode().removeChildren(); for (var i = 0; i < this._data.length; ++i) { var item = this._data[i]; if (item.folderName) { var groupData = [ item.folderName, "", "", "", "", this._totalSize(item.cookies), "", "" ]; var groupNode = new WebInspector.DataGridNode(groupData); groupNode.selectable = true; this._dataGrid.rootNode().appendChild(groupNode); groupNode.element.addStyleClass("row-group"); this._populateNode(groupNode, item.cookies); groupNode.expand(); } else this._populateNode(this._dataGrid.rootNode(), item.cookies); } }, _populateNode: function(parentNode, cookies) { var selectedCookie = this.selectedCookie; parentNode.removeChildren(); if (!cookies) return; this._sortCookies(cookies); for (var i = 0; i < cookies.length; ++i) { var cookieNode = this._createGridNode(cookies[i]); parentNode.appendChild(cookieNode); if (selectedCookie === cookies[i]) cookieNode.selected = true; } }, _totalSize: function(cookies) { var totalSize = 0; for (var i = 0; cookies && i < cookies.length; ++i) totalSize += cookies[i].size(); return totalSize; }, _sortCookies: function(cookies) { var sortDirection = this._dataGrid.sortOrder === "ascending" ? 1 : -1; function localeCompare(field, cookie1, cookie2) { return sortDirection * (cookie1[field] + "").localeCompare(cookie2[field] + "") } function numberCompare(field, cookie1, cookie2) { return sortDirection * (cookie1[field] - cookie2[field]); } function expiresCompare(cookie1, cookie2) { if (cookie1.session() !== cookie2.session()) return sortDirection * (cookie1.session() ? 1 : -1); if (cookie1.session()) return 0; if (cookie1.maxAge() && cookie2.maxAge()) return sortDirection * (cookie1.maxAge() - cookie2.maxAge()); if (cookie1.expires() && cookie2.expires()) return sortDirection * (cookie1.expires() - cookie2.expires()); return sortDirection * (cookie1.expires() ? 1 : -1); } var comparator; switch (parseInt(this._dataGrid.sortColumnIdentifier, 10)) { case 0: comparator = localeCompare.bind(this, "name"); break; case 1: comparator = localeCompare.bind(this, "value"); break; case 2: comparator = localeCompare.bind(this, "domain"); break; case 3: comparator = localeCompare.bind(this, "path"); break; case 4: comparator = expiresCompare; break; case 5: comparator = numberCompare.bind(this, "size"); break; case 6: comparator = localeCompare.bind(this, "httpOnly"); break; case 7: comparator = localeCompare.bind(this, "secure"); break; default: localeCompare.bind(this, "name"); } cookies.sort(comparator); }, _createGridNode: function(cookie) { var data = {}; data[0] = cookie.name; data[1] = cookie.value; data[2] = cookie.domain() || ""; data[3] = cookie.path() || ""; if (cookie.type === WebInspector.Cookie.Type.Request) data[4] = ""; else if (cookie.maxAge()) data[4] = Number.secondsToString(cookie.maxAge()); else if (cookie.expires()) data[4] = new Date(cookie.expires()).toGMTString(); else data[4] = WebInspector.UIString("Session"); data[5] = cookie.size(); const checkmark = "\u2713"; data[6] = (cookie.httpOnly() ? checkmark : ""); data[7] = (cookie.secure() ? checkmark : ""); var node = new WebInspector.DataGridNode(data); node.cookie = cookie; node.selectable = true; return node; }, _onDeleteFromGrid: function(deleteCallback, node) { deleteCallback(node.cookie); }, __proto__: WebInspector.View.prototype } WebInspector.CookieItemsView = function(treeElement, cookieDomain) { WebInspector.View.call(this); this.element.addStyleClass("storage-view"); this._deleteButton = new WebInspector.StatusBarButton(WebInspector.UIString("Delete"), "delete-storage-status-bar-item"); this._deleteButton.visible = false; this._deleteButton.addEventListener("click", this._deleteButtonClicked, this); this._refreshButton = new WebInspector.StatusBarButton(WebInspector.UIString("Refresh"), "refresh-storage-status-bar-item"); this._refreshButton.addEventListener("click", this._refreshButtonClicked, this); this._treeElement = treeElement; this._cookieDomain = cookieDomain; this._emptyView = new WebInspector.EmptyView(WebInspector.UIString("This site has no cookies.")); this._emptyView.show(this.element); this.element.addEventListener("contextmenu", this._contextMenu.bind(this), true); } WebInspector.CookieItemsView.prototype = { get statusBarItems() { return [this._refreshButton.element, this._deleteButton.element]; }, wasShown: function() { this._update(); }, willHide: function() { this._deleteButton.visible = false; }, _update: function() { WebInspector.Cookies.getCookiesAsync(this._updateWithCookies.bind(this)); }, _updateWithCookies: function(allCookies, isAdvanced) { this._cookies = isAdvanced ? this._filterCookiesForDomain(allCookies) : allCookies; if (!this._cookies.length) { this._emptyView.show(this.element); this._deleteButton.visible = false; if (this._cookiesTable) this._cookiesTable.detach(); return; } if (!this._cookiesTable) this._cookiesTable = isAdvanced ? new WebInspector.CookiesTable(this._cookieDomain, false, this._deleteCookie.bind(this), this._update.bind(this)) : new WebInspector.SimpleCookiesTable(); this._cookiesTable.setCookies(this._cookies); this._emptyView.detach(); this._cookiesTable.show(this.element); if (isAdvanced) { this._treeElement.subtitle = String.sprintf(WebInspector.UIString("%d cookies (%s)"), this._cookies.length, Number.bytesToString(this._totalSize)); this._deleteButton.visible = true; } }, _filterCookiesForDomain: function(allCookies) { var cookies = []; var resourceURLsForDocumentURL = []; this._totalSize = 0; function populateResourcesForDocuments(resource) { var url = resource.documentURL.asParsedURL(); if (url && url.host == this._cookieDomain) resourceURLsForDocumentURL.push(resource.url); } WebInspector.forAllResources(populateResourcesForDocuments.bind(this)); for (var i = 0; i < allCookies.length; ++i) { var pushed = false; var size = allCookies[i].size(); for (var j = 0; j < resourceURLsForDocumentURL.length; ++j) { var resourceURL = resourceURLsForDocumentURL[j]; if (WebInspector.Cookies.cookieMatchesResourceURL(allCookies[i], resourceURL)) { this._totalSize += size; if (!pushed) { pushed = true; cookies.push(allCookies[i]); } } } } return cookies; }, _deleteCookie: function(cookie) { PageAgent.deleteCookie(cookie.name, this._cookieDomain); this._update(); }, _deleteButtonClicked: function() { if (this._cookiesTable.selectedCookie) this._deleteCookie(this._cookiesTable.selectedCookie); }, _refreshButtonClicked: function(event) { this._update(); }, _contextMenu: function(event) { if (!this._cookies.length) { var contextMenu = new WebInspector.ContextMenu(event); contextMenu.appendItem(WebInspector.UIString("Refresh"), this._update.bind(this)); contextMenu.show(); } }, __proto__: WebInspector.View.prototype } WebInspector.SimpleCookiesTable = function() { WebInspector.View.call(this); var columns = {}; columns[0] = {}; columns[1] = {}; columns[0].title = WebInspector.UIString("Name"); columns[1].title = WebInspector.UIString("Value"); this._dataGrid = new WebInspector.DataGrid(columns); this._dataGrid.autoSizeColumns(20, 80); this._dataGrid.show(this.element); } WebInspector.SimpleCookiesTable.prototype = { setCookies: function(cookies) { this._dataGrid.rootNode().removeChildren(); var addedCookies = {}; for (var i = 0; i < cookies.length; ++i) { if (addedCookies[cookies[i].name]) continue; addedCookies[cookies[i].name] = true; var data = {}; data[0] = cookies[i].name; data[1] = cookies[i].value; var node = new WebInspector.DataGridNode(data, false); node.selectable = true; this._dataGrid.rootNode().appendChild(node); } this._dataGrid.rootNode().children[0].selected = true; }, __proto__: WebInspector.View.prototype } WebInspector.ApplicationCacheModel = function() { ApplicationCacheAgent.enable(); InspectorBackend.registerApplicationCacheDispatcher(new WebInspector.ApplicationCacheDispatcher(this)); WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this); WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this._frameDetached, this); this._statuses = {}; this._manifestURLsByFrame = {}; this._mainFrameNavigated(); this._onLine = true; } WebInspector.ApplicationCacheModel.EventTypes = { FrameManifestStatusUpdated: "FrameManifestStatusUpdated", FrameManifestAdded: "FrameManifestAdded", FrameManifestRemoved: "FrameManifestRemoved", NetworkStateChanged: "NetworkStateChanged" } WebInspector.ApplicationCacheModel.prototype = { _frameNavigated: function(event) { var frame = (event.data); if (frame.isMainFrame()) { this._mainFrameNavigated(); return; } ApplicationCacheAgent.getManifestForFrame(frame.id, this._manifestForFrameLoaded.bind(this, frame.id)); }, _frameDetached: function(event) { var frame = (event.data); this._frameManifestRemoved(frame.id); }, _mainFrameNavigated: function() { ApplicationCacheAgent.getFramesWithManifests(this._framesWithManifestsLoaded.bind(this)); }, _manifestForFrameLoaded: function(frameId, error, manifestURL) { if (error) { console.error(error); return; } if (!manifestURL) this._frameManifestRemoved(frameId); }, _framesWithManifestsLoaded: function(error, framesWithManifests) { if (error) { console.error(error); return; } for (var i = 0; i < framesWithManifests.length; ++i) this._frameManifestUpdated(framesWithManifests[i].frameId, framesWithManifests[i].manifestURL, framesWithManifests[i].status); }, _frameManifestUpdated: function(frameId, manifestURL, status) { if (status === applicationCache.UNCACHED) { this._frameManifestRemoved(frameId); return; } if (!manifestURL) return; if (this._manifestURLsByFrame[frameId] && manifestURL !== this._manifestURLsByFrame[frameId]) this._frameManifestRemoved(frameId); var statusChanged = this._statuses[frameId] !== status; this._statuses[frameId] = status; if (!this._manifestURLsByFrame[frameId]) { this._manifestURLsByFrame[frameId] = manifestURL; this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestAdded, frameId); } if (statusChanged) this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestStatusUpdated, frameId); }, _frameManifestRemoved: function(frameId) { if (!this._manifestURLsByFrame[frameId]) return; var manifestURL = this._manifestURLsByFrame[frameId]; delete this._manifestURLsByFrame[frameId]; delete this._statuses[frameId]; this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestRemoved, frameId); }, frameManifestURL: function(frameId) { return this._manifestURLsByFrame[frameId] || ""; }, frameManifestStatus: function(frameId) { return this._statuses[frameId] || applicationCache.UNCACHED; }, get onLine() { return this._onLine; }, _statusUpdated: function(frameId, manifestURL, status) { this._frameManifestUpdated(frameId, manifestURL, status); }, requestApplicationCache: function(frameId, callback) { function callbackWrapper(error, applicationCache) { if (error) { console.error(error); callback(null); return; } callback(applicationCache); } ApplicationCacheAgent.getApplicationCacheForFrame(frameId, callbackWrapper.bind(this)); }, _networkStateUpdated: function(isNowOnline) { this._onLine = isNowOnline; this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.NetworkStateChanged, isNowOnline); }, __proto__: WebInspector.Object.prototype } WebInspector.ApplicationCacheDispatcher = function(applicationCacheModel) { this._applicationCacheModel = applicationCacheModel; } WebInspector.ApplicationCacheDispatcher.prototype = { applicationCacheStatusUpdated: function(frameId, manifestURL, status) { this._applicationCacheModel._statusUpdated(frameId, manifestURL, status); }, networkStateUpdated: function(isNowOnline) { this._applicationCacheModel._networkStateUpdated(isNowOnline); } } WebInspector.IndexedDBModel = function() { IndexedDBAgent.enable(); WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameAdded, this._frameNavigated, this); WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this); WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this._frameDetached, this); this._frames = {}; this._databases = new Map(); this._frameIdsBySecurityOrigin = {}; this._databaseNamesBySecurityOrigin = {}; this.refreshDatabaseNames(); } WebInspector.IndexedDBModel.KeyTypes = { NumberType: "number", StringType: "string", DateType: "date", ArrayType: "array" }; WebInspector.IndexedDBModel.KeyPathTypes = { NullType: "null", StringType: "string", ArrayType: "array" }; WebInspector.IndexedDBModel.keyFromIDBKey = function(idbKey) { if (typeof(idbKey) === "undefined" || idbKey === null) return null; var key = {}; switch (typeof(idbKey)) { case "number": key.number = idbKey; key.type = WebInspector.IndexedDBModel.KeyTypes.NumberType; break; case "string": key.string = idbKey; key.type = WebInspector.IndexedDBModel.KeyTypes.StringType; break; case "object": if (idbKey instanceof Date) { key.date = idbKey.getTime(); key.type = WebInspector.IndexedDBModel.KeyTypes.DateType; } else if (idbKey instanceof Array) { key.array = []; for (var i = 0; i < idbKey.length; ++i) key.array.push(WebInspector.IndexedDBModel.keyFromIDBKey(idbKey[i])); key.type = WebInspector.IndexedDBModel.KeyTypes.ArrayType; } break; default: return null; } return key; } WebInspector.IndexedDBModel.keyRangeFromIDBKeyRange = function(idbKeyRange) { var IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange; if (typeof(idbKeyRange) === "undefined" || idbKeyRange === null) return null; var keyRange = {}; keyRange.lower = WebInspector.IndexedDBModel.keyFromIDBKey(idbKeyRange.lower); keyRange.upper = WebInspector.IndexedDBModel.keyFromIDBKey(idbKeyRange.upper); keyRange.lowerOpen = idbKeyRange.lowerOpen; keyRange.upperOpen = idbKeyRange.upperOpen; return keyRange; } WebInspector.IndexedDBModel.idbKeyPathFromKeyPath = function(keyPath) { var idbKeyPath; switch (keyPath.type) { case WebInspector.IndexedDBModel.KeyPathTypes.NullType: idbKeyPath = null; break; case WebInspector.IndexedDBModel.KeyPathTypes.StringType: idbKeyPath = keyPath.string; break; case WebInspector.IndexedDBModel.KeyPathTypes.ArrayType: idbKeyPath = keyPath.array; break; } return idbKeyPath; } WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath = function(idbKeyPath) { if (typeof idbKeyPath === "string") return "\"" + idbKeyPath + "\""; if (idbKeyPath instanceof Array) return "[\"" + idbKeyPath.join("\", \"") + "\"]"; return null; } WebInspector.IndexedDBModel.EventTypes = { DatabaseAdded: "DatabaseAdded", DatabaseRemoved: "DatabaseRemoved", DatabaseLoaded: "DatabaseLoaded" } WebInspector.IndexedDBModel.prototype = { refreshDatabaseNames: function() { this._reset(); if (WebInspector.resourceTreeModel.mainFrame) this._framesNavigatedRecursively(WebInspector.resourceTreeModel.mainFrame); }, refreshDatabase: function(databaseId) { this._loadDatabase(databaseId); }, _framesNavigatedRecursively: function(resourceTreeFrame) { this._processFrameNavigated(resourceTreeFrame); for (var i = 0; i < resourceTreeFrame.childFrames.length; ++i) this._framesNavigatedRecursively(resourceTreeFrame.childFrames[i]); }, _frameNavigated: function(event) { var resourceTreeFrame = (event.data); this._processFrameNavigated(resourceTreeFrame); }, _frameDetached: function(event) { var resourceTreeFrame = (event.data); this._originRemovedFromFrame(resourceTreeFrame.id); }, _reset: function() { for (var frameId in this._frames) this._originRemovedFromFrame(frameId); }, _processFrameNavigated: function(resourceTreeFrame) { if (resourceTreeFrame.securityOrigin === "null") return; if (this._frameIdsBySecurityOrigin[resourceTreeFrame.securityOrigin]) this._originAddedToFrame(resourceTreeFrame.id, resourceTreeFrame.securityOrigin); else this._loadDatabaseNamesForFrame(resourceTreeFrame.id); }, _originAddedToFrame: function(frameId, securityOrigin) { if (!this._frameIdsBySecurityOrigin[securityOrigin]) { this._frameIdsBySecurityOrigin[securityOrigin] = []; this._frameIdsBySecurityOrigin[securityOrigin].push(frameId); this._databaseNamesBySecurityOrigin[securityOrigin] = []; } this._frames[frameId] = new WebInspector.IndexedDBModel.Frame(frameId, securityOrigin); }, _originRemovedFromFrame: function(frameId) { var currentSecurityOrigin = this._frames[frameId] ? this._frames[frameId].securityOrigin : null; if (!currentSecurityOrigin) return; delete this._frames[frameId]; var frameIdsForOrigin = this._frameIdsBySecurityOrigin[currentSecurityOrigin]; for (var i = 0; i < frameIdsForOrigin; ++i) { if (frameIdsForOrigin[i] === frameId) { frameIdsForOrigin.splice(i, 1); break; } } if (!frameIdsForOrigin.length) this._originRemoved(currentSecurityOrigin); }, _originRemoved: function(securityOrigin) { var frameIdsForOrigin = this._frameIdsBySecurityOrigin[securityOrigin]; for (var i = 0; i < frameIdsForOrigin; ++i) delete this._frames[frameIdsForOrigin[i]]; delete this._frameIdsBySecurityOrigin[securityOrigin]; for (var i = 0; i < this._databaseNamesBySecurityOrigin[securityOrigin].length; ++i) this._databaseRemoved(securityOrigin, this._databaseNamesBySecurityOrigin[securityOrigin][i]); delete this._databaseNamesBySecurityOrigin[securityOrigin]; }, _updateOriginDatabaseNames: function(securityOrigin, databaseNames) { var newDatabaseNames = {}; for (var i = 0; i < databaseNames.length; ++i) newDatabaseNames[databaseNames[i]] = true; var oldDatabaseNames = {}; for (var i = 0; i < this._databaseNamesBySecurityOrigin[securityOrigin].length; ++i) oldDatabaseNames[databaseNames[i]] = true; this._databaseNamesBySecurityOrigin[securityOrigin] = databaseNames; for (var databaseName in oldDatabaseNames) { if (!newDatabaseNames[databaseName]) this._databaseRemoved(securityOrigin, databaseName); } for (var databaseName in newDatabaseNames) { if (!oldDatabaseNames[databaseName]) this._databaseAdded(securityOrigin, databaseName); } if (!this._databaseNamesBySecurityOrigin[securityOrigin].length) this._originRemoved(securityOrigin); }, _databaseAdded: function(securityOrigin, databaseName) { var databaseId = new WebInspector.IndexedDBModel.DatabaseId(securityOrigin, databaseName); this.dispatchEventToListeners(WebInspector.IndexedDBModel.EventTypes.DatabaseAdded, databaseId); }, _databaseRemoved: function(securityOrigin, databaseName) { var databaseId = new WebInspector.IndexedDBModel.DatabaseId(securityOrigin, databaseName); this.dispatchEventToListeners(WebInspector.IndexedDBModel.EventTypes.DatabaseRemoved, databaseId); }, _loadDatabaseNamesForFrame: function(frameId) { function callback(error, securityOriginWithDatabaseNames) { if (error) { console.error("IndexedDBAgent error: " + error); return; } var databaseNames = securityOriginWithDatabaseNames.databaseNames; var oldSecurityOrigin = this._frames[frameId] ? this._frames[frameId].securityOrigin : null; if (!oldSecurityOrigin || oldSecurityOrigin !== securityOriginWithDatabaseNames.securityOrigin) { this._originRemovedFromFrame(frameId); this._originAddedToFrame(frameId, securityOriginWithDatabaseNames.securityOrigin); } this._updateOriginDatabaseNames(securityOriginWithDatabaseNames.securityOrigin, securityOriginWithDatabaseNames.databaseNames); } IndexedDBAgent.requestDatabaseNamesForFrame(frameId, callback.bind(this)); }, _assertFrameId: function(databaseId) { var frameIds = this._frameIdsBySecurityOrigin[databaseId.securityOrigin]; if (!frameIds || !frameIds.length) return null; return frameIds[0]; }, _loadDatabase: function(databaseId) { var frameId = this._assertFrameId(databaseId); if (!frameId) return; function callback(error, databaseWithObjectStores) { if (error) { console.error("IndexedDBAgent error: " + error); return; } if (!this._frames[frameId]) return; var databaseModel = new WebInspector.IndexedDBModel.Database(databaseId, databaseWithObjectStores.version, databaseWithObjectStores.intVersion); this._databases.put(databaseId, databaseModel); for (var i = 0; i < databaseWithObjectStores.objectStores.length; ++i) { var objectStore = databaseWithObjectStores.objectStores[i]; var objectStoreIDBKeyPath = WebInspector.IndexedDBModel.idbKeyPathFromKeyPath(objectStore.keyPath); var objectStoreModel = new WebInspector.IndexedDBModel.ObjectStore(objectStore.name, objectStoreIDBKeyPath, objectStore.autoIncrement); for (var j = 0; j < objectStore.indexes.length; ++j) { var index = objectStore.indexes[j]; var indexIDBKeyPath = WebInspector.IndexedDBModel.idbKeyPathFromKeyPath(index.keyPath); var indexModel = new WebInspector.IndexedDBModel.Index(index.name, indexIDBKeyPath, index.unique, index.multiEntry); objectStoreModel.indexes[indexModel.name] = indexModel; } databaseModel.objectStores[objectStoreModel.name] = objectStoreModel; } this.dispatchEventToListeners(WebInspector.IndexedDBModel.EventTypes.DatabaseLoaded, databaseModel); } IndexedDBAgent.requestDatabase(frameId, databaseId.name, callback.bind(this)); }, loadObjectStoreData: function(databaseId, objectStoreName, idbKeyRange, skipCount, pageSize, callback) { this._requestData(databaseId, databaseId.name, objectStoreName, "", idbKeyRange, skipCount, pageSize, callback); }, loadIndexData: function(databaseId, objectStoreName, indexName, idbKeyRange, skipCount, pageSize, callback) { this._requestData(databaseId, databaseId.name, objectStoreName, indexName, idbKeyRange, skipCount, pageSize, callback); }, _requestData: function(databaseId, databaseName, objectStoreName, indexName, idbKeyRange, skipCount, pageSize, callback) { var frameId = this._assertFrameId(databaseId); if (!frameId) return; function innerCallback(error, dataEntries, hasMore) { if (error) { console.error("IndexedDBAgent error: " + error); return; } if (!this._frames[frameId]) return; var entries = []; for (var i = 0; i < dataEntries.length; ++i) { var key = WebInspector.RemoteObject.fromPayload(dataEntries[i].key); var primaryKey = WebInspector.RemoteObject.fromPayload(dataEntries[i].primaryKey); var value = WebInspector.RemoteObject.fromPayload(dataEntries[i].value); entries.push(new WebInspector.IndexedDBModel.Entry(key, primaryKey, value)); } callback(entries, hasMore); } var keyRange = WebInspector.IndexedDBModel.keyRangeFromIDBKeyRange(idbKeyRange); IndexedDBAgent.requestData(frameId, databaseName, objectStoreName, indexName, skipCount, pageSize, keyRange ? keyRange : undefined, innerCallback.bind(this)); }, __proto__: WebInspector.Object.prototype } WebInspector.IndexedDBModel.Entry = function(key, primaryKey, value) { this.key = key; this.primaryKey = primaryKey; this.value = value; } WebInspector.IndexedDBModel.Frame = function(frameId, securityOrigin) { this.frameId = frameId; this.securityOrigin = securityOrigin; this.databaseNames = {}; } WebInspector.IndexedDBModel.DatabaseId = function(securityOrigin, name) { this.securityOrigin = securityOrigin; this.name = name; } WebInspector.IndexedDBModel.DatabaseId.prototype = { equals: function(databaseId) { return this.name === databaseId.name && this.securityOrigin === databaseId.securityOrigin; }, } WebInspector.IndexedDBModel.Database = function(databaseId, version, intVersion) { this.databaseId = databaseId; this.version = version; this.intVersion = intVersion; this.objectStores = {}; } WebInspector.IndexedDBModel.ObjectStore = function(name, keyPath, autoIncrement) { this.name = name; this.keyPath = keyPath; this.autoIncrement = autoIncrement; this.indexes = {}; } WebInspector.IndexedDBModel.ObjectStore.prototype = { get keyPathString() { return WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath(this.keyPath); } } WebInspector.IndexedDBModel.Index = function(name, keyPath, unique, multiEntry) { this.name = name; this.keyPath = keyPath; this.unique = unique; this.multiEntry = multiEntry; } WebInspector.IndexedDBModel.Index.prototype = { get keyPathString() { return WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath(this.keyPath); } } WebInspector.Spectrum = function() { WebInspector.View.call(this); this.registerRequiredCSS("spectrum.css"); this.element.className = "spectrum-container"; this.element.tabIndex = 0; var topElement = this.element.createChild("div", "spectrum-top"); topElement.createChild("div", "spectrum-fill"); var topInnerElement = topElement.createChild("div", "spectrum-top-inner fill"); this._draggerElement = topInnerElement.createChild("div", "spectrum-color"); this._dragHelperElement = this._draggerElement.createChild("div", "spectrum-sat fill").createChild("div", "spectrum-val fill").createChild("div", "spectrum-dragger"); this._sliderElement = topInnerElement.createChild("div", "spectrum-hue"); this.slideHelper = this._sliderElement.createChild("div", "spectrum-slider"); var rangeContainer = this.element.createChild("div", "spectrum-range-container"); var alphaLabel = rangeContainer.createChild("label"); alphaLabel.textContent = WebInspector.UIString("\u03B1:"); this._alphaElement = rangeContainer.createChild("input", "spectrum-range"); this._alphaElement.setAttribute("type", "range"); this._alphaElement.setAttribute("min", "0"); this._alphaElement.setAttribute("max", "100"); this._alphaElement.addEventListener("change", alphaDrag.bind(this), false); var swatchElement = document.createElement("span"); swatchElement.className = "swatch"; this._swatchInnerElement = swatchElement.createChild("span", "swatch-inner"); var displayContainer = this.element.createChild("div"); displayContainer.appendChild(swatchElement); this._displayElement = displayContainer.createChild("span", "source-code spectrum-display-value"); WebInspector.Spectrum.draggable(this._sliderElement, hueDrag.bind(this)); WebInspector.Spectrum.draggable(this._draggerElement, colorDrag.bind(this), colorDragStart.bind(this)); function hueDrag(element, dragX, dragY) { this.hsv[0] = (dragY / this.slideHeight); this._onchange(); } var initialHelperOffset; function colorDragStart(element, dragX, dragY) { initialHelperOffset = { x: this._dragHelperElement.offsetLeft, y: this._dragHelperElement.offsetTop }; } function colorDrag(element, dragX, dragY, event) { if (event.shiftKey) { if (Math.abs(dragX - initialHelperOffset.x) >= Math.abs(dragY - initialHelperOffset.y)) dragY = initialHelperOffset.y; else dragX = initialHelperOffset.x; } this.hsv[1] = dragX / this.dragWidth; this.hsv[2] = (this.dragHeight - dragY) / this.dragHeight; this._onchange(); } function alphaDrag() { this.hsv[3] = this._alphaElement.value / 100; this._onchange(); } }; WebInspector.Spectrum.Events = { ColorChanged: "ColorChanged" }; WebInspector.Spectrum.hsvaToRGBA = function(h, s, v, a) { var r, g, b; var i = Math.floor(h * 6); var f = h * 6 - i; var p = v * (1 - s); var q = v * (1 - f * s); var t = v * (1 - (1 - f) * s); switch(i % 6) { case 0: r = v, g = t, b = p; break; case 1: r = q, g = v, b = p; break; case 2: r = p, g = v, b = t; break; case 3: r = p, g = q, b = v; break; case 4: r = t, g = p, b = v; break; case 5: r = v, g = p, b = q; break; } return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), a]; }; WebInspector.Spectrum.rgbaToHSVA = function(r, g, b, a) { r = r / 255; g = g / 255; b = b / 255; var max = Math.max(r, g, b); var min = Math.min(r, g, b); var h; var s; var v = max; var d = max - min; s = max ? d / max : 0; if(max === min) { h = 0; } else { switch(max) { case r: h = (g - b) / d + (g < b ? 6 : 0); break; case g: h = (b - r) / d + 2; break; case b: h = (r - g) / d + 4; break; } h /= 6; } return [h, s, v, a]; }; WebInspector.Spectrum.draggable = function(element, onmove, onstart, onstop) { var doc = document; var dragging; var offset; var scrollOffset; var maxHeight; var maxWidth; function consume(e) { e.consume(true); } function move(e) { if (dragging) { var dragX = Math.max(0, Math.min(e.pageX - offset.left + scrollOffset.left, maxWidth)); var dragY = Math.max(0, Math.min(e.pageY - offset.top + scrollOffset.top, maxHeight)); if (onmove) onmove(element, dragX, dragY, e); } } function start(e) { var rightClick = e.which ? (e.which === 3) : (e.button === 2); if (!rightClick && !dragging) { if (onstart) onstart(element, e) dragging = true; maxHeight = element.clientHeight; maxWidth = element.clientWidth; scrollOffset = element.scrollOffset(); offset = element.totalOffset(); doc.addEventListener("selectstart", consume, false); doc.addEventListener("dragstart", consume, false); doc.addEventListener("mousemove", move, false); doc.addEventListener("mouseup", stop, false); move(e); consume(e); } } function stop(e) { if (dragging) { doc.removeEventListener("selectstart", consume, false); doc.removeEventListener("dragstart", consume, false); doc.removeEventListener("mousemove", move, false); doc.removeEventListener("mouseup", stop, false); if (onstop) onstop(element, e); } dragging = false; } element.addEventListener("mousedown", start, false); }; WebInspector.Spectrum.prototype = { set color(color) { var rgba = (color.rgba || color.rgb).slice(0); if (rgba.length === 3) rgba[3] = 1; this.hsv = WebInspector.Spectrum.rgbaToHSVA(rgba[0], rgba[1], rgba[2], rgba[3]); }, get color() { var rgba = WebInspector.Spectrum.hsvaToRGBA(this.hsv[0], this.hsv[1], this.hsv[2], this.hsv[3]); var color; if (rgba[3] === 1) color = WebInspector.Color.fromRGB(rgba[0], rgba[1], rgba[2]); else color = WebInspector.Color.fromRGBA(rgba[0], rgba[1], rgba[2], rgba[3]); var colorValue = color.toString(this.outputColorFormat); if (!colorValue) colorValue = color.toString(); return new WebInspector.Color(colorValue); }, get outputColorFormat() { var cf = WebInspector.Color.Format; var format = this._originalFormat; if (this.hsv[3] === 1) { if (format === cf.RGBA) format = cf.RGB; else if (format === cf.HSLA) format = cf.HSL; } else { if (format === cf.HSL || format === cf.HSLA) format = cf.HSLA; else format = cf.RGBA; } return format; }, get colorHueOnly() { var rgba = WebInspector.Spectrum.hsvaToRGBA(this.hsv[0], 1, 1, 1); return WebInspector.Color.fromRGBA(rgba[0], rgba[1], rgba[2], rgba[3]); }, set displayText(text) { this._displayElement.textContent = text; }, _onchange: function() { this._updateUI(); this.dispatchEventToListeners(WebInspector.Spectrum.Events.ColorChanged, this.color); }, _updateHelperLocations: function() { var h = this.hsv[0]; var s = this.hsv[1]; var v = this.hsv[2]; var dragX = s * this.dragWidth; var dragY = this.dragHeight - (v * this.dragHeight); dragX = Math.max(-this._dragHelperElementHeight, Math.min(this.dragWidth - this._dragHelperElementHeight, dragX - this._dragHelperElementHeight)); dragY = Math.max(-this._dragHelperElementHeight, Math.min(this.dragHeight - this._dragHelperElementHeight, dragY - this._dragHelperElementHeight)); this._dragHelperElement.positionAt(dragX, dragY); var slideY = (h * this.slideHeight) - this.slideHelperHeight; this.slideHelper.style.top = slideY + "px"; this._alphaElement.value = this.hsv[3] * 100; }, _updateUI: function() { this._updateHelperLocations(); var rgb = (this.color.rgba || this.color.rgb).slice(0); if (rgb.length === 3) rgb[3] = 1; var rgbHueOnly = this.colorHueOnly.rgb; var flatColor = "rgb(" + rgbHueOnly[0] + ", " + rgbHueOnly[1] + ", " + rgbHueOnly[2] + ")"; var fullColor = "rgba(" + rgb[0] + ", " + rgb[1] + ", " + rgb[2] + ", " + rgb[3] + ")"; this._draggerElement.style.backgroundColor = flatColor; this._swatchInnerElement.style.backgroundColor = fullColor; this._alphaElement.value = this.hsv[3] * 100; }, wasShown: function() { this.slideHeight = this._sliderElement.offsetHeight; this.dragWidth = this._draggerElement.offsetWidth; this.dragHeight = this._draggerElement.offsetHeight; this._dragHelperElementHeight = this._dragHelperElement.offsetHeight / 2; this.slideHelperHeight = this.slideHelper.offsetHeight / 2; this._updateUI(); }, __proto__: WebInspector.View.prototype } WebInspector.SpectrumPopupHelper = function() { this._spectrum = new WebInspector.Spectrum(); this._spectrum.element.addEventListener("keydown", this._onKeyDown.bind(this), false); this._popover = new WebInspector.Popover(); this._popover.setCanShrink(false); this._popover.element.addEventListener("mousedown", consumeEvent, false); this._hideProxy = this.hide.bind(this, true); } WebInspector.SpectrumPopupHelper.Events = { Hidden: "Hidden" }; WebInspector.SpectrumPopupHelper.prototype = { spectrum: function() { return this._spectrum; }, toggle: function(element, color, format) { if (this._popover.isShowing()) this.hide(true); else this.show(element, color, format); return this._popover.isShowing(); }, show: function(element, color, format) { if (this._popover.isShowing()) { if (this._anchorElement === element) return false; this.hide(true); } this._anchorElement = element; this._spectrum.color = color; this._spectrum._originalFormat = format || color.format; this.reposition(element); document.addEventListener("mousedown", this._hideProxy, false); window.addEventListener("blur", this._hideProxy, false); return true; }, reposition: function(element) { if (!this._previousFocusElement) this._previousFocusElement = WebInspector.currentFocusElement(); this._popover.showView(this._spectrum, element); WebInspector.setCurrentFocusElement(this._spectrum.element); }, hide: function(commitEdit) { if (!this._popover.isShowing()) return; this._popover.hide(); document.removeEventListener("mousedown", this._hideProxy, false); window.removeEventListener("blur", this._hideProxy, false); this.dispatchEventToListeners(WebInspector.SpectrumPopupHelper.Events.Hidden, !!commitEdit); WebInspector.setCurrentFocusElement(this._previousFocusElement); delete this._previousFocusElement; delete this._anchorElement; }, _onKeyDown: function(event) { if (event.keyIdentifier === "Enter") { this.hide(true); event.consume(true); return; } if (event.keyIdentifier === "U+001B") { this.hide(false); event.consume(true); } }, __proto__: WebInspector.Object.prototype } WebInspector.ColorSwatch = function() { this.element = document.createElement("span"); this._swatchInnerElement = this.element.createChild("span", "swatch-inner"); this.element.title = WebInspector.UIString("Click to open a colorpicker. Shift-click to change color format"); this.element.className = "swatch"; this.element.addEventListener("mousedown", consumeEvent, false); this.element.addEventListener("dblclick", consumeEvent, false); } WebInspector.ColorSwatch.prototype = { setColorString: function(colorString) { this._swatchInnerElement.style.backgroundColor = colorString; } } WebInspector.SidebarPane = function(title) { this.element = document.createElement("div"); this.element.className = "pane"; this.titleElement = document.createElement("div"); this.titleElement.className = "title"; this.titleElement.tabIndex = 0; this.titleElement.addEventListener("click", this.toggleExpanded.bind(this), false); this.titleElement.addEventListener("keydown", this._onTitleKeyDown.bind(this), false); this.bodyElement = document.createElement("div"); this.bodyElement.className = "body"; this.element.appendChild(this.titleElement); this.element.appendChild(this.bodyElement); this.title = title; this.growbarVisible = false; this.expanded = false; } WebInspector.SidebarPane.prototype = { get title() { return this._title; }, set title(x) { if (this._title === x) return; this._title = x; this.titleElement.textContent = x; }, get growbarVisible() { return this._growbarVisible; }, set growbarVisible(x) { if (this._growbarVisible === x) return; this._growbarVisible = x; if (x && !this._growbarElement) { this._growbarElement = document.createElement("div"); this._growbarElement.className = "growbar"; this.element.appendChild(this._growbarElement); } else if (!x && this._growbarElement) { if (this._growbarElement.parentNode) this._growbarElement.parentNode(this._growbarElement); delete this._growbarElement; } }, get expanded() { return this._expanded; }, set expanded(x) { if (x) this.expand(); else this.collapse(); }, expand: function() { if (this._expanded) return; this._expanded = true; this.element.addStyleClass("expanded"); this.onexpand(); }, onexpand: function() { }, collapse: function() { if (!this._expanded) return; this._expanded = false; this.element.removeStyleClass("expanded"); }, toggleExpanded: function() { this.expanded = !this.expanded; }, _onTitleKeyDown: function(event) { if (isEnterKey(event) || event.keyCode === WebInspector.KeyboardShortcut.Keys.Space.code) this.toggleExpanded(); }, __proto__: WebInspector.Object.prototype } WebInspector.ElementsTreeOutline = function(omitRootDOMNode, selectEnabled, showInElementsPanelEnabled, contextMenuCallback, setPseudoClassCallback) { this.element = document.createElement("ol"); this.element.addEventListener("mousedown", this._onmousedown.bind(this), false); this.element.addEventListener("mousemove", this._onmousemove.bind(this), false); this.element.addEventListener("mouseout", this._onmouseout.bind(this), false); this.element.addEventListener("dragstart", this._ondragstart.bind(this), false); this.element.addEventListener("dragover", this._ondragover.bind(this), false); this.element.addEventListener("dragleave", this._ondragleave.bind(this), false); this.element.addEventListener("drop", this._ondrop.bind(this), false); this.element.addEventListener("dragend", this._ondragend.bind(this), false); TreeOutline.call(this, this.element); this._includeRootDOMNode = !omitRootDOMNode; this._selectEnabled = selectEnabled; this._showInElementsPanelEnabled = showInElementsPanelEnabled; this._rootDOMNode = null; this._selectDOMNode = null; this._eventSupport = new WebInspector.Object(); this._editing = false; this._visible = false; this.element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true); this._contextMenuCallback = contextMenuCallback; this._setPseudoClassCallback = setPseudoClassCallback; this._createNodeDecorators(); } WebInspector.ElementsTreeOutline.Events = { SelectedNodeChanged: "SelectedNodeChanged" } WebInspector.ElementsTreeOutline.MappedCharToEntity = { "\u00a0": "nbsp", "\u2002": "ensp", "\u2003": "emsp", "\u2009": "thinsp", "\u200b": "#8203", "\u200c": "zwnj", "\u200d": "zwj", "\u200e": "lrm", "\u200f": "rlm", "\u202a": "#8234", "\u202b": "#8235", "\u202c": "#8236", "\u202d": "#8237", "\u202e": "#8238" } WebInspector.ElementsTreeOutline.prototype = { _createNodeDecorators: function() { this._nodeDecorators = []; this._nodeDecorators.push(new WebInspector.ElementsTreeOutline.PseudoStateDecorator()); }, wireToDomAgent: function() { this._elementsTreeUpdater = new WebInspector.ElementsTreeUpdater(this); }, setVisible: function(visible) { this._visible = visible; if (!this._visible) return; this._updateModifiedNodes(); if (this._selectedDOMNode) this._revealAndSelectNode(this._selectedDOMNode, false); }, addEventListener: function(eventType, listener, thisObject) { this._eventSupport.addEventListener(eventType, listener, thisObject); }, removeEventListener: function(eventType, listener, thisObject) { this._eventSupport.removeEventListener(eventType, listener, thisObject); }, get rootDOMNode() { return this._rootDOMNode; }, set rootDOMNode(x) { if (this._rootDOMNode === x) return; this._rootDOMNode = x; this._isXMLMimeType = x && x.isXMLNode(); this.update(); }, get isXMLMimeType() { return this._isXMLMimeType; }, selectedDOMNode: function() { return this._selectedDOMNode; }, selectDOMNode: function(node, focus) { if (this._selectedDOMNode === node) { this._revealAndSelectNode(node, !focus); return; } this._selectedDOMNode = node; this._revealAndSelectNode(node, !focus); if (this._selectedDOMNode === node) this._selectedNodeChanged(); }, get editing() { return this._editing; }, update: function() { var selectedNode = this.selectedTreeElement ? this.selectedTreeElement.representedObject : null; this.removeChildren(); if (!this.rootDOMNode) return; var treeElement; if (this._includeRootDOMNode) { treeElement = new WebInspector.ElementsTreeElement(this.rootDOMNode); treeElement.selectable = this._selectEnabled; this.appendChild(treeElement); } else { var node = this.rootDOMNode.firstChild; while (node) { treeElement = new WebInspector.ElementsTreeElement(node); treeElement.selectable = this._selectEnabled; this.appendChild(treeElement); node = node.nextSibling; } } if (selectedNode) this._revealAndSelectNode(selectedNode, true); }, updateSelection: function() { if (!this.selectedTreeElement) return; var element = this.treeOutline.selectedTreeElement; element.updateSelection(); }, updateOpenCloseTags: function(node) { var treeElement = this.findTreeElement(node); if (treeElement) treeElement.updateTitle(); var children = treeElement.children; var closingTagElement = children[children.length - 1]; if (closingTagElement && closingTagElement._elementCloseTag) closingTagElement.updateTitle(); }, _selectedNodeChanged: function() { this._eventSupport.dispatchEventToListeners(WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged, this._selectedDOMNode); }, findTreeElement: function(node) { function isAncestorNode(ancestor, node) { return ancestor.isAncestor(node); } function parentNode(node) { return node.parentNode; } var treeElement = TreeOutline.prototype.findTreeElement.call(this, node, isAncestorNode, parentNode); if (!treeElement && node.nodeType() === Node.TEXT_NODE) { treeElement = TreeOutline.prototype.findTreeElement.call(this, node.parentNode, isAncestorNode, parentNode); } return treeElement; }, createTreeElementFor: function(node) { var treeElement = this.findTreeElement(node); if (treeElement) return treeElement; if (!node.parentNode) return null; treeElement = this.createTreeElementFor(node.parentNode); if (treeElement && treeElement.showChild(node.index)) return treeElement.children[node.index]; return null; }, set suppressRevealAndSelect(x) { if (this._suppressRevealAndSelect === x) return; this._suppressRevealAndSelect = x; }, _revealAndSelectNode: function(node, omitFocus) { if (!node || this._suppressRevealAndSelect) return; var treeElement = this.createTreeElementFor(node); if (!treeElement) return; treeElement.revealAndSelect(omitFocus); }, _treeElementFromEvent: function(event) { var scrollContainer = this.element.parentElement; var x = scrollContainer.totalOffsetLeft() + scrollContainer.offsetWidth - 36; var y = event.pageY; var elementUnderMouse = this.treeElementFromPoint(x, y); var elementAboveMouse = this.treeElementFromPoint(x, y - 2); var element; if (elementUnderMouse === elementAboveMouse) element = elementUnderMouse; else element = this.treeElementFromPoint(x, y + 2); return element; }, _onmousedown: function(event) { var element = this._treeElementFromEvent(event); if (!element || element.isEventWithinDisclosureTriangle(event)) return; element.select(); }, _onmousemove: function(event) { var element = this._treeElementFromEvent(event); if (element && this._previousHoveredElement === element) return; if (this._previousHoveredElement) { this._previousHoveredElement.hovered = false; delete this._previousHoveredElement; } if (element) { element.hovered = true; this._previousHoveredElement = element; } WebInspector.domAgent.highlightDOMNode(element ? element.representedObject.id : 0); }, _onmouseout: function(event) { var nodeUnderMouse = document.elementFromPoint(event.pageX, event.pageY); if (nodeUnderMouse && nodeUnderMouse.isDescendant(this.element)) return; if (this._previousHoveredElement) { this._previousHoveredElement.hovered = false; delete this._previousHoveredElement; } WebInspector.domAgent.hideDOMNodeHighlight(); }, _ondragstart: function(event) { if (!window.getSelection().isCollapsed) return false; if (event.target.nodeName === "A") return false; var treeElement = this._treeElementFromEvent(event); if (!treeElement) return false; if (!this._isValidDragSourceOrTarget(treeElement)) return false; if (treeElement.representedObject.nodeName() === "BODY" || treeElement.representedObject.nodeName() === "HEAD") return false; event.dataTransfer.setData("text/plain", treeElement.listItemElement.textContent); event.dataTransfer.effectAllowed = "copyMove"; this._treeElementBeingDragged = treeElement; WebInspector.domAgent.hideDOMNodeHighlight(); return true; }, _ondragover: function(event) { if (!this._treeElementBeingDragged) return false; var treeElement = this._treeElementFromEvent(event); if (!this._isValidDragSourceOrTarget(treeElement)) return false; var node = treeElement.representedObject; while (node) { if (node === this._treeElementBeingDragged.representedObject) return false; node = node.parentNode; } treeElement.updateSelection(); treeElement.listItemElement.addStyleClass("elements-drag-over"); this._dragOverTreeElement = treeElement; event.preventDefault(); event.dataTransfer.dropEffect = 'move'; return false; }, _ondragleave: function(event) { this._clearDragOverTreeElementMarker(); event.preventDefault(); return false; }, _isValidDragSourceOrTarget: function(treeElement) { if (!treeElement) return false; var node = treeElement.representedObject; if (!(node instanceof WebInspector.DOMNode)) return false; if (!node.parentNode || node.parentNode.nodeType() !== Node.ELEMENT_NODE) return false; return true; }, _ondrop: function(event) { event.preventDefault(); var treeElement = this._treeElementFromEvent(event); if (treeElement) this._doMove(treeElement); }, _doMove: function(treeElement) { if (!this._treeElementBeingDragged) return; var parentNode; var anchorNode; if (treeElement._elementCloseTag) { parentNode = treeElement.representedObject; } else { var dragTargetNode = treeElement.representedObject; parentNode = dragTargetNode.parentNode; anchorNode = dragTargetNode; } var wasExpanded = this._treeElementBeingDragged.expanded; this._treeElementBeingDragged.representedObject.moveTo(parentNode, anchorNode, this._selectNodeAfterEdit.bind(this, null, wasExpanded)); delete this._treeElementBeingDragged; }, _ondragend: function(event) { event.preventDefault(); this._clearDragOverTreeElementMarker(); delete this._treeElementBeingDragged; }, _clearDragOverTreeElementMarker: function() { if (this._dragOverTreeElement) { this._dragOverTreeElement.updateSelection(); this._dragOverTreeElement.listItemElement.removeStyleClass("elements-drag-over"); delete this._dragOverTreeElement; } }, _contextMenuEventFired: function(event) { if (!this._showInElementsPanelEnabled) return; var treeElement = this._treeElementFromEvent(event); if (!treeElement) return; function focusElement() { WebInspector.domAgent.inspectElement(treeElement.representedObject.id); } var contextMenu = new WebInspector.ContextMenu(event); contextMenu.appendItem(WebInspector.UIString("Reveal in Elements Panel"), focusElement.bind(this)); contextMenu.show(); }, populateContextMenu: function(contextMenu, event) { var treeElement = this._treeElementFromEvent(event); if (!treeElement) return false; var isTag = treeElement.representedObject.nodeType() === Node.ELEMENT_NODE; var textNode = event.target.enclosingNodeOrSelfWithClass("webkit-html-text-node"); if (textNode && textNode.hasStyleClass("bogus")) textNode = null; var commentNode = event.target.enclosingNodeOrSelfWithClass("webkit-html-comment"); contextMenu.appendApplicableItems(event.target); if (textNode) { contextMenu.appendSeparator(); treeElement._populateTextContextMenu(contextMenu, textNode); } else if (isTag) { contextMenu.appendSeparator(); treeElement._populateTagContextMenu(contextMenu, event); } else if (commentNode) { contextMenu.appendSeparator(); treeElement._populateNodeContextMenu(contextMenu, textNode); } }, adjustCollapsedRange: function() { }, _updateModifiedNodes: function() { if (this._elementsTreeUpdater) this._elementsTreeUpdater._updateModifiedNodes(); }, _populateContextMenu: function(contextMenu, node) { if (this._contextMenuCallback) this._contextMenuCallback(contextMenu, node); }, handleShortcut: function(event) { var node = this.selectedDOMNode(); var treeElement = this.getCachedTreeElement(node); if (!node || !treeElement) return; if (event.keyIdentifier === "F2") { this._toggleEditAsHTML(node); return; } if (WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) && node.parentNode) { if (event.keyIdentifier === "Up" && node.previousSibling) { node.moveTo(node.parentNode, node.previousSibling, this._selectNodeAfterEdit.bind(this, null, treeElement.expanded)); return; } if (event.keyIdentifier === "Down" && node.nextSibling) { node.moveTo(node.parentNode, node.nextSibling.nextSibling, this._selectNodeAfterEdit.bind(this, null, treeElement.expanded)); return; } } }, _toggleEditAsHTML: function(node) { var treeElement = this.getCachedTreeElement(node); if (!treeElement) return; if (treeElement._editing && treeElement._htmlEditElement && WebInspector.isBeingEdited(treeElement._htmlEditElement)) treeElement._editing.commit(); else treeElement._editAsHTML(); }, _selectNodeAfterEdit: function(fallbackNode, wasExpanded, error, nodeId) { if (error) return; this._updateModifiedNodes(); var newNode = WebInspector.domAgent.nodeForId(nodeId) || fallbackNode; if (!newNode) return; this.selectDOMNode(newNode, true); var newTreeItem = this.findTreeElement(newNode); if (wasExpanded) { if (newTreeItem) newTreeItem.expand(); } return newTreeItem; }, __proto__: TreeOutline.prototype } WebInspector.ElementsTreeOutline.ElementDecorator = function() { } WebInspector.ElementsTreeOutline.ElementDecorator.prototype = { decorate: function(node) { }, decorateAncestor: function(node) { } } WebInspector.ElementsTreeOutline.PseudoStateDecorator = function() { WebInspector.ElementsTreeOutline.ElementDecorator.call(this); } WebInspector.ElementsTreeOutline.PseudoStateDecorator.PropertyName = "pseudoState"; WebInspector.ElementsTreeOutline.PseudoStateDecorator.prototype = { decorate: function(node) { if (node.nodeType() !== Node.ELEMENT_NODE) return null; var propertyValue = node.getUserProperty(WebInspector.ElementsTreeOutline.PseudoStateDecorator.PropertyName); if (!propertyValue) return null; return WebInspector.UIString("Element state: %s", ":" + propertyValue.join(", :")); }, decorateAncestor: function(node) { if (node.nodeType() !== Node.ELEMENT_NODE) return null; var descendantCount = node.descendantUserPropertyCount(WebInspector.ElementsTreeOutline.PseudoStateDecorator.PropertyName); if (!descendantCount) return null; if (descendantCount === 1) return WebInspector.UIString("%d descendant with forced state", descendantCount); return WebInspector.UIString("%d descendants with forced state", descendantCount); }, __proto__: WebInspector.ElementsTreeOutline.ElementDecorator.prototype } WebInspector.ElementsTreeElement = function(node, elementCloseTag) { this._elementCloseTag = elementCloseTag; var hasChildrenOverride = !elementCloseTag && node.hasChildNodes() && !this._showInlineText(node); TreeElement.call(this, "", node, hasChildrenOverride); if (this.representedObject.nodeType() == Node.ELEMENT_NODE && !elementCloseTag) this._canAddAttributes = true; this._searchQuery = null; this._expandedChildrenLimit = WebInspector.ElementsTreeElement.InitialChildrenLimit; } WebInspector.ElementsTreeElement.InitialChildrenLimit = 500; WebInspector.ElementsTreeElement.ForbiddenClosingTagElements = [ "area", "base", "basefont", "br", "canvas", "col", "command", "embed", "frame", "hr", "img", "input", "isindex", "keygen", "link", "meta", "param", "source" ].keySet(); WebInspector.ElementsTreeElement.EditTagBlacklist = [ "html", "head", "body" ].keySet(); WebInspector.ElementsTreeElement.prototype = { highlightSearchResults: function(searchQuery) { if (this._searchQuery !== searchQuery) { this._updateSearchHighlight(false); delete this._highlightResult; } this._searchQuery = searchQuery; this._searchHighlightsVisible = true; this.updateTitle(true); }, hideSearchHighlights: function() { delete this._searchHighlightsVisible; this._updateSearchHighlight(false); }, _updateSearchHighlight: function(show) { if (!this._highlightResult) return; function updateEntryShow(entry) { switch (entry.type) { case "added": entry.parent.insertBefore(entry.node, entry.nextSibling); break; case "changed": entry.node.textContent = entry.newText; break; } } function updateEntryHide(entry) { switch (entry.type) { case "added": if (entry.node.parentElement) entry.node.parentElement.removeChild(entry.node); break; case "changed": entry.node.textContent = entry.oldText; break; } } if (show) { for (var i = 0, size = this._highlightResult.length; i < size; ++i) updateEntryShow(this._highlightResult[i]); } else { for (var i = (this._highlightResult.length - 1); i >= 0; --i) updateEntryHide(this._highlightResult[i]); } }, get hovered() { return this._hovered; }, set hovered(x) { if (this._hovered === x) return; this._hovered = x; if (this.listItemElement) { if (x) { this.updateSelection(); this.listItemElement.addStyleClass("hovered"); } else { this.listItemElement.removeStyleClass("hovered"); } } }, get expandedChildrenLimit() { return this._expandedChildrenLimit; }, set expandedChildrenLimit(x) { if (this._expandedChildrenLimit === x) return; this._expandedChildrenLimit = x; if (this.treeOutline && !this._updateChildrenInProgress) this._updateChildren(true); }, get expandedChildCount() { var count = this.children.length; if (count && this.children[count - 1]._elementCloseTag) count--; if (count && this.children[count - 1].expandAllButton) count--; return count; }, showChild: function(index) { if (this._elementCloseTag) return; if (index >= this.expandedChildrenLimit) { this._expandedChildrenLimit = index + 1; this._updateChildren(true); } return this.expandedChildCount > index; }, updateSelection: function() { var listItemElement = this.listItemElement; if (!listItemElement) return; if (!this._readyToUpdateSelection) { if (document.body.offsetWidth > 0) this._readyToUpdateSelection = true; else { return; } } if (!this.selectionElement) { this.selectionElement = document.createElement("div"); this.selectionElement.className = "selection selected"; listItemElement.insertBefore(this.selectionElement, listItemElement.firstChild); } this.selectionElement.style.height = listItemElement.offsetHeight + "px"; }, onattach: function() { if (this._hovered) { this.updateSelection(); this.listItemElement.addStyleClass("hovered"); } this.updateTitle(); this._preventFollowingLinksOnDoubleClick(); this.listItemElement.draggable = true; }, _preventFollowingLinksOnDoubleClick: function() { var links = this.listItemElement.querySelectorAll("li > .webkit-html-tag > .webkit-html-attribute > .webkit-html-external-link, li > .webkit-html-tag > .webkit-html-attribute > .webkit-html-resource-link"); if (!links) return; for (var i = 0; i < links.length; ++i) links[i].preventFollowOnDoubleClick = true; }, onpopulate: function() { if (this.children.length || this._showInlineText(this.representedObject) || this._elementCloseTag) return; this.updateChildren(); }, updateChildren: function(fullRefresh) { if (this._elementCloseTag) return; this.representedObject.getChildNodes(this._updateChildren.bind(this, fullRefresh)); }, insertChildElement: function(child, index, closingTag) { var newElement = new WebInspector.ElementsTreeElement(child, closingTag); newElement.selectable = this.treeOutline._selectEnabled; this.insertChild(newElement, index); return newElement; }, moveChild: function(child, targetIndex) { var wasSelected = child.selected; this.removeChild(child); this.insertChild(child, targetIndex); if (wasSelected) child.select(); }, _updateChildren: function(fullRefresh) { if (this._updateChildrenInProgress || !this.treeOutline._visible) return; this._updateChildrenInProgress = true; var selectedNode = this.treeOutline.selectedDOMNode(); var originalScrollTop = 0; if (fullRefresh) { var treeOutlineContainerElement = this.treeOutline.element.parentNode; originalScrollTop = treeOutlineContainerElement.scrollTop; var selectedTreeElement = this.treeOutline.selectedTreeElement; if (selectedTreeElement && selectedTreeElement.hasAncestor(this)) this.select(); this.removeChildren(); } var treeElement = this; var treeChildIndex = 0; var elementToSelect; function updateChildrenOfNode(node) { var treeOutline = treeElement.treeOutline; var child = node.firstChild; while (child) { var currentTreeElement = treeElement.children[treeChildIndex]; if (!currentTreeElement || currentTreeElement.representedObject !== child) { var existingTreeElement = null; for (var i = (treeChildIndex + 1), size = treeElement.expandedChildCount; i < size; ++i) { if (treeElement.children[i].representedObject === child) { existingTreeElement = treeElement.children[i]; break; } } if (existingTreeElement && existingTreeElement.parent === treeElement) { treeElement.moveChild(existingTreeElement, treeChildIndex); } else { if (treeChildIndex < treeElement.expandedChildrenLimit) { var newElement = treeElement.insertChildElement(child, treeChildIndex); if (child === selectedNode) elementToSelect = newElement; if (treeElement.expandedChildCount > treeElement.expandedChildrenLimit) treeElement.expandedChildrenLimit++; } } } child = child.nextSibling; ++treeChildIndex; } } for (var i = (this.children.length - 1); i >= 0; --i) { var currentChild = this.children[i]; var currentNode = currentChild.representedObject; var currentParentNode = currentNode.parentNode; if (currentParentNode === this.representedObject) continue; var selectedTreeElement = this.treeOutline.selectedTreeElement; if (selectedTreeElement && (selectedTreeElement === currentChild || selectedTreeElement.hasAncestor(currentChild))) this.select(); this.removeChildAtIndex(i); } updateChildrenOfNode(this.representedObject); this.adjustCollapsedRange(); var lastChild = this.children[this.children.length - 1]; if (this.representedObject.nodeType() == Node.ELEMENT_NODE && (!lastChild || !lastChild._elementCloseTag)) this.insertChildElement(this.representedObject, this.children.length, true); if (fullRefresh && elementToSelect) { elementToSelect.select(); if (treeOutlineContainerElement && originalScrollTop <= treeOutlineContainerElement.scrollHeight) treeOutlineContainerElement.scrollTop = originalScrollTop; } delete this._updateChildrenInProgress; }, adjustCollapsedRange: function() { if (this.expandAllButtonElement && this.expandAllButtonElement.__treeElement.parent) this.removeChild(this.expandAllButtonElement.__treeElement); const node = this.representedObject; if (!node.children) return; const childNodeCount = node.children.length; for (var i = this.expandedChildCount, limit = Math.min(this.expandedChildrenLimit, childNodeCount); i < limit; ++i) this.insertChildElement(node.children[i], i); const expandedChildCount = this.expandedChildCount; if (childNodeCount > this.expandedChildCount) { var targetButtonIndex = expandedChildCount; if (!this.expandAllButtonElement) { var button = document.createElement("button"); button.className = "show-all-nodes"; button.value = ""; var item = new TreeElement(button, null, false); item.selectable = false; item.expandAllButton = true; this.insertChild(item, targetButtonIndex); this.expandAllButtonElement = item.listItemElement.firstChild; this.expandAllButtonElement.__treeElement = item; this.expandAllButtonElement.addEventListener("click", this.handleLoadAllChildren.bind(this), false); } else if (!this.expandAllButtonElement.__treeElement.parent) this.insertChild(this.expandAllButtonElement.__treeElement, targetButtonIndex); this.expandAllButtonElement.textContent = WebInspector.UIString("Show All Nodes (%d More)", childNodeCount - expandedChildCount); } else if (this.expandAllButtonElement) delete this.expandAllButtonElement; }, handleLoadAllChildren: function() { this.expandedChildrenLimit = Math.max(this.representedObject._childNodeCount, this.expandedChildrenLimit + WebInspector.ElementsTreeElement.InitialChildrenLimit); }, onexpand: function() { if (this._elementCloseTag) return; this.updateTitle(); this.treeOutline.updateSelection(); }, oncollapse: function() { if (this._elementCloseTag) return; this.updateTitle(); this.treeOutline.updateSelection(); }, onreveal: function() { if (this.listItemElement) { var tagSpans = this.listItemElement.getElementsByClassName("webkit-html-tag-name"); if (tagSpans.length) tagSpans[0].scrollIntoViewIfNeeded(false); else this.listItemElement.scrollIntoViewIfNeeded(false); } }, onselect: function(selectedByUser) { this.treeOutline.suppressRevealAndSelect = true; this.treeOutline.selectDOMNode(this.representedObject, selectedByUser); if (selectedByUser) WebInspector.domAgent.highlightDOMNode(this.representedObject.id); this.updateSelection(); this.treeOutline.suppressRevealAndSelect = false; return true; }, ondelete: function() { var startTagTreeElement = this.treeOutline.findTreeElement(this.representedObject); startTagTreeElement ? startTagTreeElement.remove() : this.remove(); return true; }, onenter: function() { if (this.treeOutline.editing) return false; this._startEditing(); return true; }, selectOnMouseDown: function(event) { TreeElement.prototype.selectOnMouseDown.call(this, event); if (this._editing) return; if (this.treeOutline._showInElementsPanelEnabled) { WebInspector.showPanel("elements"); this.treeOutline.selectDOMNode(this.representedObject, true); } if (event.detail >= 2) event.preventDefault(); }, ondblclick: function(event) { if (this._editing || this._elementCloseTag) return; if (this._startEditingTarget(event.target)) return; if (this.hasChildren && !this.expanded) this.expand(); }, _insertInLastAttributePosition: function(tag, node) { if (tag.getElementsByClassName("webkit-html-attribute").length > 0) tag.insertBefore(node, tag.lastChild); else { var nodeName = tag.textContent.match(/^<(.*?)>$/)[1]; tag.textContent = ''; tag.appendChild(document.createTextNode('<'+nodeName)); tag.appendChild(node); tag.appendChild(document.createTextNode('>')); } this.updateSelection(); }, _startEditingTarget: function(eventTarget) { if (this.treeOutline.selectedDOMNode() != this.representedObject) return; if (this.representedObject.nodeType() != Node.ELEMENT_NODE && this.representedObject.nodeType() != Node.TEXT_NODE) return false; var textNode = eventTarget.enclosingNodeOrSelfWithClass("webkit-html-text-node"); if (textNode) return this._startEditingTextNode(textNode); var attribute = eventTarget.enclosingNodeOrSelfWithClass("webkit-html-attribute"); if (attribute) return this._startEditingAttribute(attribute, eventTarget); var tagName = eventTarget.enclosingNodeOrSelfWithClass("webkit-html-tag-name"); if (tagName) return this._startEditingTagName(tagName); var newAttribute = eventTarget.enclosingNodeOrSelfWithClass("add-attribute"); if (newAttribute) return this._addNewAttribute(); return false; }, _populateTagContextMenu: function(contextMenu, event) { var attribute = event.target.enclosingNodeOrSelfWithClass("webkit-html-attribute"); var newAttribute = event.target.enclosingNodeOrSelfWithClass("add-attribute"); contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Add attribute" : "Add Attribute"), this._addNewAttribute.bind(this)); if (attribute && !newAttribute) contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Edit attribute" : "Edit Attribute"), this._startEditingAttribute.bind(this, attribute, event.target)); contextMenu.appendSeparator(); if (this.treeOutline._setPseudoClassCallback) { var pseudoSubMenu = contextMenu.appendSubMenuItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Force element state" : "Force Element State")); this._populateForcedPseudoStateItems(pseudoSubMenu); contextMenu.appendSeparator(); } this._populateNodeContextMenu(contextMenu); this.treeOutline._populateContextMenu(contextMenu, this.representedObject); contextMenu.appendSeparator(); contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Scroll into view" : "Scroll Into View"), this._scrollIntoView.bind(this)); }, _populateForcedPseudoStateItems: function(subMenu) { const pseudoClasses = ["active", "hover", "focus", "visited"]; var node = this.representedObject; var forcedPseudoState = (node ? node.getUserProperty("pseudoState") : null) || []; for (var i = 0; i < pseudoClasses.length; ++i) { var pseudoClassForced = forcedPseudoState.indexOf(pseudoClasses[i]) >= 0; subMenu.appendCheckboxItem(":" + pseudoClasses[i], this.treeOutline._setPseudoClassCallback.bind(null, node.id, pseudoClasses[i], !pseudoClassForced), pseudoClassForced, false); } }, _populateTextContextMenu: function(contextMenu, textNode) { contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Edit text" : "Edit Text"), this._startEditingTextNode.bind(this, textNode)); this._populateNodeContextMenu(contextMenu); }, _populateNodeContextMenu: function(contextMenu) { contextMenu.appendItem(WebInspector.UIString("Edit as HTML"), this._editAsHTML.bind(this)); contextMenu.appendItem(WebInspector.UIString("Copy as HTML"), this._copyHTML.bind(this)); contextMenu.appendItem(WebInspector.UIString("Copy XPath"), this._copyXPath.bind(this)); contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Delete node" : "Delete Node"), this.remove.bind(this)); }, _startEditing: function() { if (this.treeOutline.selectedDOMNode() !== this.representedObject) return; var listItem = this._listItemNode; if (this._canAddAttributes) { var attribute = listItem.getElementsByClassName("webkit-html-attribute")[0]; if (attribute) return this._startEditingAttribute(attribute, attribute.getElementsByClassName("webkit-html-attribute-value")[0]); return this._addNewAttribute(); } if (this.representedObject.nodeType() === Node.TEXT_NODE) { var textNode = listItem.getElementsByClassName("webkit-html-text-node")[0]; if (textNode) return this._startEditingTextNode(textNode); return; } }, _addNewAttribute: function() { var container = document.createElement("span"); this._buildAttributeDOM(container, " ", ""); var attr = container.firstChild; attr.style.marginLeft = "2px"; attr.style.marginRight = "2px"; var tag = this.listItemElement.getElementsByClassName("webkit-html-tag")[0]; this._insertInLastAttributePosition(tag, attr); return this._startEditingAttribute(attr, attr); }, _triggerEditAttribute: function(attributeName) { var attributeElements = this.listItemElement.getElementsByClassName("webkit-html-attribute-name"); for (var i = 0, len = attributeElements.length; i < len; ++i) { if (attributeElements[i].textContent === attributeName) { for (var elem = attributeElements[i].nextSibling; elem; elem = elem.nextSibling) { if (elem.nodeType !== Node.ELEMENT_NODE) continue; if (elem.hasStyleClass("webkit-html-attribute-value")) return this._startEditingAttribute(elem.parentNode, elem); } } } }, _startEditingAttribute: function(attribute, elementForSelection) { if (WebInspector.isBeingEdited(attribute)) return true; var attributeNameElement = attribute.getElementsByClassName("webkit-html-attribute-name")[0]; if (!attributeNameElement) return false; var attributeName = attributeNameElement.textContent; function removeZeroWidthSpaceRecursive(node) { if (node.nodeType === Node.TEXT_NODE) { node.nodeValue = node.nodeValue.replace(/\u200B/g, ""); return; } if (node.nodeType !== Node.ELEMENT_NODE) return; for (var child = node.firstChild; child; child = child.nextSibling) removeZeroWidthSpaceRecursive(child); } removeZeroWidthSpaceRecursive(attribute); var config = new WebInspector.EditingConfig(this._attributeEditingCommitted.bind(this), this._editingCancelled.bind(this), attributeName); function handleKeyDownEvents(event) { var isMetaOrCtrl = WebInspector.isMac() ? event.metaKey && !event.shiftKey && !event.ctrlKey && !event.altKey : event.ctrlKey && !event.shiftKey && !event.metaKey && !event.altKey; if (isEnterKey(event) && (event.isMetaOrCtrlForTest || !config.multiline || isMetaOrCtrl)) return "commit"; else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code || event.keyIdentifier === "U+001B") return "cancel"; else if (event.keyIdentifier === "U+0009") return "move-" + (event.shiftKey ? "backward" : "forward"); else { WebInspector.handleElementValueModifications(event, attribute); return ""; } } config.customFinishHandler = handleKeyDownEvents.bind(this); this._editing = WebInspector.startEditing(attribute, config); window.getSelection().setBaseAndExtent(elementForSelection, 0, elementForSelection, 1); return true; }, _startEditingTextNode: function(textNodeElement) { if (WebInspector.isBeingEdited(textNodeElement)) return true; var textNode = this.representedObject; if (textNode.nodeType() === Node.ELEMENT_NODE && textNode.firstChild) textNode = textNode.firstChild; var container = textNodeElement.enclosingNodeOrSelfWithClass("webkit-html-text-node"); if (container) container.textContent = textNode.nodeValue(); var config = new WebInspector.EditingConfig(this._textNodeEditingCommitted.bind(this, textNode), this._editingCancelled.bind(this)); this._editing = WebInspector.startEditing(textNodeElement, config); window.getSelection().setBaseAndExtent(textNodeElement, 0, textNodeElement, 1); return true; }, _startEditingTagName: function(tagNameElement) { if (!tagNameElement) { tagNameElement = this.listItemElement.getElementsByClassName("webkit-html-tag-name")[0]; if (!tagNameElement) return false; } var tagName = tagNameElement.textContent; if (WebInspector.ElementsTreeElement.EditTagBlacklist[tagName.toLowerCase()]) return false; if (WebInspector.isBeingEdited(tagNameElement)) return true; var closingTagElement = this._distinctClosingTagElement(); function keyupListener(event) { if (closingTagElement) closingTagElement.textContent = "</" + tagNameElement.textContent + ">"; } function editingComitted(element, newTagName) { tagNameElement.removeEventListener('keyup', keyupListener, false); this._tagNameEditingCommitted.apply(this, arguments); } function editingCancelled() { tagNameElement.removeEventListener('keyup', keyupListener, false); this._editingCancelled.apply(this, arguments); } tagNameElement.addEventListener('keyup', keyupListener, false); var config = new WebInspector.EditingConfig(editingComitted.bind(this), editingCancelled.bind(this), tagName); this._editing = WebInspector.startEditing(tagNameElement, config); window.getSelection().setBaseAndExtent(tagNameElement, 0, tagNameElement, 1); return true; }, _startEditingAsHTML: function(commitCallback, error, initialValue) { if (error) return; if (this._htmlEditElement && WebInspector.isBeingEdited(this._htmlEditElement)) return; function consume(event) { if (event.eventPhase === Event.AT_TARGET) event.consume(true); } initialValue = this._convertWhitespaceToEntities(initialValue); this._htmlEditElement = document.createElement("div"); this._htmlEditElement.className = "source-code elements-tree-editor"; this._htmlEditElement.textContent = initialValue; var child = this.listItemElement.firstChild; while (child) { child.style.display = "none"; child = child.nextSibling; } if (this._childrenListNode) this._childrenListNode.style.display = "none"; this.listItemElement.appendChild(this._htmlEditElement); this.treeOutline.childrenListElement.parentElement.addEventListener("mousedown", consume, false); this.updateSelection(); function commit() { commitCallback(initialValue, this._htmlEditElement.textContent); dispose.call(this); } function dispose() { this._editing = false; this.listItemElement.removeChild(this._htmlEditElement); delete this._htmlEditElement; if (this._childrenListNode) this._childrenListNode.style.removeProperty("display"); var child = this.listItemElement.firstChild; while (child) { child.style.removeProperty("display"); child = child.nextSibling; } this.treeOutline.childrenListElement.parentElement.removeEventListener("mousedown", consume, false); this.updateSelection(); } var config = new WebInspector.EditingConfig(commit.bind(this), dispose.bind(this)); config.setMultiline(true); this._editing = WebInspector.startEditing(this._htmlEditElement, config); }, _attributeEditingCommitted: function(element, newText, oldText, attributeName, moveDirection) { this._editing = false; var treeOutline = this.treeOutline; function moveToNextAttributeIfNeeded(error) { if (error) this._editingCancelled(element, attributeName); if (!moveDirection) return; treeOutline._updateModifiedNodes(); var attributes = this.representedObject.attributes(); for (var i = 0; i < attributes.length; ++i) { if (attributes[i].name !== attributeName) continue; if (moveDirection === "backward") { if (i === 0) this._startEditingTagName(); else this._triggerEditAttribute(attributes[i - 1].name); } else { if (i === attributes.length - 1) this._addNewAttribute(); else this._triggerEditAttribute(attributes[i + 1].name); } return; } if (moveDirection === "backward") { if (newText === " ") { if (attributes.length > 0) this._triggerEditAttribute(attributes[attributes.length - 1].name); } else { if (attributes.length > 1) this._triggerEditAttribute(attributes[attributes.length - 2].name); } } else if (moveDirection === "forward") { if (!/^\s*$/.test(newText)) this._addNewAttribute(); else this._startEditingTagName(); } } if (oldText !== newText) this.representedObject.setAttribute(attributeName, newText, moveToNextAttributeIfNeeded.bind(this)); else moveToNextAttributeIfNeeded.call(this); }, _tagNameEditingCommitted: function(element, newText, oldText, tagName, moveDirection) { this._editing = false; var self = this; function cancel() { var closingTagElement = self._distinctClosingTagElement(); if (closingTagElement) closingTagElement.textContent = "</" + tagName + ">"; self._editingCancelled(element, tagName); moveToNextAttributeIfNeeded.call(self); } function moveToNextAttributeIfNeeded() { if (moveDirection !== "forward") { this._addNewAttribute(); return; } var attributes = this.representedObject.attributes(); if (attributes.length > 0) this._triggerEditAttribute(attributes[0].name); else this._addNewAttribute(); } newText = newText.trim(); if (newText === oldText) { cancel(); return; } var treeOutline = this.treeOutline; var wasExpanded = this.expanded; function changeTagNameCallback(error, nodeId) { if (error || !nodeId) { cancel(); return; } var newTreeItem = treeOutline._selectNodeAfterEdit(null, wasExpanded, error, nodeId); moveToNextAttributeIfNeeded.call(newTreeItem); } this.representedObject.setNodeName(newText, changeTagNameCallback); }, _textNodeEditingCommitted: function(textNode, element, newText) { this._editing = false; function callback() { this.updateTitle(); } textNode.setNodeValue(newText, callback.bind(this)); }, _editingCancelled: function(element, context) { this._editing = false; this.updateTitle(); }, _distinctClosingTagElement: function() { if (this.expanded) { var closers = this._childrenListNode.querySelectorAll(".close"); return closers[closers.length-1]; } var tags = this.listItemElement.getElementsByClassName("webkit-html-tag"); return (tags.length === 1 ? null : tags[tags.length-1]); }, updateTitle: function(onlySearchQueryChanged) { if (this._editing) return; if (onlySearchQueryChanged) { if (this._highlightResult) this._updateSearchHighlight(false); } else { var highlightElement = document.createElement("span"); highlightElement.className = "highlight"; highlightElement.appendChild(this._nodeTitleInfo(WebInspector.linkifyURLAsNode).titleDOM); this.title = highlightElement; this._updateDecorations(); delete this._highlightResult; } delete this.selectionElement; if (this.selected) this.updateSelection(); this._preventFollowingLinksOnDoubleClick(); this._highlightSearchResults(); }, _createDecoratorElement: function() { var node = this.representedObject; var decoratorMessages = []; var parentDecoratorMessages = []; for (var i = 0; i < this.treeOutline._nodeDecorators.length; ++i) { var decorator = this.treeOutline._nodeDecorators[i]; var message = decorator.decorate(node); if (message) { decoratorMessages.push(message); continue; } if (this.expanded || this._elementCloseTag) continue; message = decorator.decorateAncestor(node); if (message) parentDecoratorMessages.push(message) } if (!decoratorMessages.length && !parentDecoratorMessages.length) return null; var decoratorElement = document.createElement("div"); decoratorElement.addStyleClass("elements-gutter-decoration"); if (!decoratorMessages.length) decoratorElement.addStyleClass("elements-has-decorated-children"); decoratorElement.title = decoratorMessages.concat(parentDecoratorMessages).join("\n"); return decoratorElement; }, _updateDecorations: function() { if (this._decoratorElement && this._decoratorElement.parentElement) this._decoratorElement.parentElement.removeChild(this._decoratorElement); this._decoratorElement = this._createDecoratorElement(); if (this._decoratorElement && this.listItemElement) this.listItemElement.insertBefore(this._decoratorElement, this.listItemElement.firstChild); }, _buildAttributeDOM: function(parentElement, name, value, node, linkify) { var hasText = (value.length > 0); var attrSpanElement = parentElement.createChild("span", "webkit-html-attribute"); var attrNameElement = attrSpanElement.createChild("span", "webkit-html-attribute-name"); attrNameElement.textContent = name; if (hasText) attrSpanElement.appendChild(document.createTextNode("=\u200B\"")); if (linkify && (name === "src" || name === "href")) { var rewrittenHref = node.resolveURL(value); value = value.replace(/([\/;:\)\]\}])/g, "$1\u200B"); if (rewrittenHref === null) { var attrValueElement = attrSpanElement.createChild("span", "webkit-html-attribute-value"); attrValueElement.textContent = value; } else { if (value.startsWith("data:")) value = value.trimMiddle(60); attrSpanElement.appendChild(linkify(rewrittenHref, value, "webkit-html-attribute-value", node.nodeName().toLowerCase() === "a")); } } else { value = value.replace(/([\/;:\)\]\}])/g, "$1\u200B"); var attrValueElement = attrSpanElement.createChild("span", "webkit-html-attribute-value"); attrValueElement.textContent = value; } if (hasText) attrSpanElement.appendChild(document.createTextNode("\"")); }, _buildTagDOM: function(parentElement, tagName, isClosingTag, isDistinctTreeElement, linkify) { var node = (this.representedObject); var classes = [ "webkit-html-tag" ]; if (isClosingTag && isDistinctTreeElement) classes.push("close"); if (node.isInShadowTree()) classes.push("shadow"); var tagElement = parentElement.createChild("span", classes.join(" ")); tagElement.appendChild(document.createTextNode("<")); var tagNameElement = tagElement.createChild("span", isClosingTag ? "" : "webkit-html-tag-name"); tagNameElement.textContent = (isClosingTag ? "/" : "") + tagName; if (!isClosingTag && node.hasAttributes()) { var attributes = node.attributes(); for (var i = 0; i < attributes.length; ++i) { var attr = attributes[i]; tagElement.appendChild(document.createTextNode(" ")); this._buildAttributeDOM(tagElement, attr.name, attr.value, node, linkify); } } tagElement.appendChild(document.createTextNode(">")); parentElement.appendChild(document.createTextNode("\u200B")); }, _convertWhitespaceToEntities: function(text) { var result = ""; var lastIndexAfterEntity = 0; var charToEntity = WebInspector.ElementsTreeOutline.MappedCharToEntity; for (var i = 0, size = text.length; i < size; ++i) { var char = text.charAt(i); if (charToEntity[char]) { result += text.substring(lastIndexAfterEntity, i) + "&" + charToEntity[char] + ";"; lastIndexAfterEntity = i + 1; } } if (result) { result += text.substring(lastIndexAfterEntity); return result; } return text; }, _nodeTitleInfo: function(linkify) { var node = this.representedObject; var info = {titleDOM: document.createDocumentFragment(), hasChildren: this.hasChildren}; switch (node.nodeType()) { case Node.ATTRIBUTE_NODE: var value = node.value || "\u200B"; this._buildAttributeDOM(info.titleDOM, node.name, value); break; case Node.ELEMENT_NODE: var tagName = node.nodeNameInCorrectCase(); if (this._elementCloseTag) { this._buildTagDOM(info.titleDOM, tagName, true, true); info.hasChildren = false; break; } this._buildTagDOM(info.titleDOM, tagName, false, false, linkify); var textChild = this._singleTextChild(node); var showInlineText = textChild && textChild.nodeValue().length < Preferences.maxInlineTextChildLength && !this.hasChildren; if (!this.expanded && (!showInlineText && (this.treeOutline.isXMLMimeType || !WebInspector.ElementsTreeElement.ForbiddenClosingTagElements[tagName]))) { if (this.hasChildren) { var textNodeElement = info.titleDOM.createChild("span", "webkit-html-text-node bogus"); textNodeElement.textContent = "\u2026"; info.titleDOM.appendChild(document.createTextNode("\u200B")); } this._buildTagDOM(info.titleDOM, tagName, true, false); } if (showInlineText) { var textNodeElement = info.titleDOM.createChild("span", "webkit-html-text-node"); textNodeElement.textContent = this._convertWhitespaceToEntities(textChild.nodeValue()); info.titleDOM.appendChild(document.createTextNode("\u200B")); this._buildTagDOM(info.titleDOM, tagName, true, false); info.hasChildren = false; } break; case Node.TEXT_NODE: if (node.parentNode && node.parentNode.nodeName().toLowerCase() === "script") { var newNode = info.titleDOM.createChild("span", "webkit-html-text-node webkit-html-js-node"); newNode.textContent = node.nodeValue(); var javascriptSyntaxHighlighter = new WebInspector.DOMSyntaxHighlighter("text/javascript", true); javascriptSyntaxHighlighter.syntaxHighlightNode(newNode); } else if (node.parentNode && node.parentNode.nodeName().toLowerCase() === "style") { var newNode = info.titleDOM.createChild("span", "webkit-html-text-node webkit-html-css-node"); newNode.textContent = node.nodeValue(); var cssSyntaxHighlighter = new WebInspector.DOMSyntaxHighlighter("text/css", true); cssSyntaxHighlighter.syntaxHighlightNode(newNode); } else { info.titleDOM.appendChild(document.createTextNode("\"")); var textNodeElement = info.titleDOM.createChild("span", "webkit-html-text-node"); textNodeElement.textContent = this._convertWhitespaceToEntities(node.nodeValue()); info.titleDOM.appendChild(document.createTextNode("\"")); } break; case Node.COMMENT_NODE: var commentElement = info.titleDOM.createChild("span", "webkit-html-comment"); commentElement.appendChild(document.createTextNode("<!--" + node.nodeValue() + "-->")); break; case Node.DOCUMENT_TYPE_NODE: var docTypeElement = info.titleDOM.createChild("span", "webkit-html-doctype"); docTypeElement.appendChild(document.createTextNode("<!DOCTYPE " + node.nodeName())); if (node.publicId) { docTypeElement.appendChild(document.createTextNode(" PUBLIC \"" + node.publicId + "\"")); if (node.systemId) docTypeElement.appendChild(document.createTextNode(" \"" + node.systemId + "\"")); } else if (node.systemId) docTypeElement.appendChild(document.createTextNode(" SYSTEM \"" + node.systemId + "\"")); if (node.internalSubset) docTypeElement.appendChild(document.createTextNode(" [" + node.internalSubset + "]")); docTypeElement.appendChild(document.createTextNode(">")); break; case Node.CDATA_SECTION_NODE: var cdataElement = info.titleDOM.createChild("span", "webkit-html-text-node"); cdataElement.appendChild(document.createTextNode("<![CDATA[" + node.nodeValue() + "]]>")); break; case Node.DOCUMENT_FRAGMENT_NODE: var fragmentElement = info.titleDOM.createChild("span", "webkit-html-fragment"); fragmentElement.textContent = node.nodeNameInCorrectCase().collapseWhitespace(); if (node.isInShadowTree()) fragmentElement.addStyleClass("shadow"); break; default: info.titleDOM.appendChild(document.createTextNode(node.nodeNameInCorrectCase().collapseWhitespace())); } return info; }, _singleTextChild: function(node) { if (!node) return null; var firstChild = node.firstChild; if (!firstChild || firstChild.nodeType() !== Node.TEXT_NODE) return null; if (node.hasShadowRoots()) return null; var sibling = firstChild.nextSibling; return sibling ? null : firstChild; }, _showInlineText: function(node) { if (node.nodeType() === Node.ELEMENT_NODE) { var textChild = this._singleTextChild(node); if (textChild && textChild.nodeValue().length < Preferences.maxInlineTextChildLength) return true; } return false; }, remove: function() { var parentElement = this.parent; if (!parentElement) return; var self = this; function removeNodeCallback(error, removedNodeId) { if (error) return; parentElement.removeChild(self); parentElement.adjustCollapsedRange(); } if (!this.representedObject.parentNode || this.representedObject.parentNode.nodeType() === Node.DOCUMENT_NODE) return; this.representedObject.removeNode(removeNodeCallback); }, _editAsHTML: function() { var treeOutline = this.treeOutline; var node = this.representedObject; var parentNode = node.parentNode; var index = node.index; var wasExpanded = this.expanded; function selectNode(error, nodeId) { if (error) return; treeOutline._updateModifiedNodes(); var newNode = parentNode ? parentNode.children[index] || parentNode : null; if (!newNode) return; treeOutline.selectDOMNode(newNode, true); if (wasExpanded) { var newTreeItem = treeOutline.findTreeElement(newNode); if (newTreeItem) newTreeItem.expand(); } } function commitChange(initialValue, value) { if (initialValue !== value) node.setOuterHTML(value, selectNode); else return; } node.getOuterHTML(this._startEditingAsHTML.bind(this, commitChange)); }, _copyHTML: function() { this.representedObject.copyNode(); }, _copyXPath: function() { this.representedObject.copyXPath(true); }, _highlightSearchResults: function() { if (!this._searchQuery || !this._searchHighlightsVisible) return; if (this._highlightResult) { this._updateSearchHighlight(true); return; } var text = this.listItemElement.textContent; var regexObject = createPlainTextSearchRegex(this._searchQuery, "gi"); var offset = 0; var match = regexObject.exec(text); var matchRanges = []; while (match) { matchRanges.push({ offset: match.index, length: match[0].length }); match = regexObject.exec(text); } if (!matchRanges.length) matchRanges.push({ offset: 0, length: text.length }); this._highlightResult = []; WebInspector.highlightSearchResults(this.listItemElement, matchRanges, this._highlightResult); }, _scrollIntoView: function() { function scrollIntoViewCallback(object) { function scrollIntoView() { this.scrollIntoViewIfNeeded(true); } if (object) object.callFunction(scrollIntoView); } var node = (this.representedObject); WebInspector.RemoteObject.resolveNode(node, "", scrollIntoViewCallback); }, __proto__: TreeElement.prototype } WebInspector.ElementsTreeUpdater = function(treeOutline) { WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.NodeInserted, this._nodeInserted, this); WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.NodeRemoved, this._nodeRemoved, this); WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.AttrModified, this._attributesUpdated, this); WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.AttrRemoved, this._attributesUpdated, this); WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.CharacterDataModified, this._characterDataModified, this); WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.DocumentUpdated, this._documentUpdated, this); WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.ChildNodeCountUpdated, this._childNodeCountUpdated, this); this._treeOutline = treeOutline; this._recentlyModifiedNodes = new Map(); } WebInspector.ElementsTreeUpdater.prototype = { _nodeModified: function(node, isUpdated, parentNode) { if (this._treeOutline._visible) this._updateModifiedNodesSoon(); var entry = (this._recentlyModifiedNodes.get(node)); if (!entry) { entry = new WebInspector.ElementsTreeUpdater.UpdateEntry(isUpdated, parentNode); this._recentlyModifiedNodes.put(node, entry); return; } entry.isUpdated |= isUpdated; if (parentNode) entry.parent = parentNode; }, _documentUpdated: function(event) { var inspectedRootDocument = event.data; this._reset(); if (!inspectedRootDocument) return; this._treeOutline.rootDOMNode = inspectedRootDocument; }, _attributesUpdated: function(event) { this._nodeModified(event.data.node, true); }, _characterDataModified: function(event) { this._nodeModified(event.data, true); }, _nodeInserted: function(event) { this._nodeModified(event.data, false, event.data.parentNode); }, _nodeRemoved: function(event) { this._nodeModified(event.data.node, false, event.data.parent); }, _childNodeCountUpdated: function(event) { var treeElement = this._treeOutline.findTreeElement(event.data); if (treeElement) treeElement.hasChildren = event.data.hasChildNodes(); }, _updateModifiedNodesSoon: function() { if (this._updateModifiedNodesTimeout) return; this._updateModifiedNodesTimeout = setTimeout(this._updateModifiedNodes.bind(this), 50); }, _updateModifiedNodes: function() { if (this._updateModifiedNodesTimeout) { clearTimeout(this._updateModifiedNodesTimeout); delete this._updateModifiedNodesTimeout; } var updatedParentTreeElements = []; var hidePanelWhileUpdating = this._recentlyModifiedNodes.size() > 10; if (hidePanelWhileUpdating) { var treeOutlineContainerElement = this._treeOutline.element.parentNode; this._treeOutline.element.addStyleClass("hidden"); var originalScrollTop = treeOutlineContainerElement ? treeOutlineContainerElement.scrollTop : 0; } var keys = this._recentlyModifiedNodes.keys(); for (var i = 0, size = keys.length; i < size; ++i) { var node = keys[i]; var entry = this._recentlyModifiedNodes.get(node); var parent = entry.parent; if (parent === this._treeOutline._rootDOMNode) { this._treeOutline.update(); this._treeOutline.element.removeStyleClass("hidden"); return; } if (entry.isUpdated) { var nodeItem = this._treeOutline.findTreeElement(node); if (nodeItem) nodeItem.updateTitle(); } if (!parent) continue; var parentNodeItem = this._treeOutline.findTreeElement(parent); if (parentNodeItem && !parentNodeItem.alreadyUpdatedChildren) { parentNodeItem.updateChildren(); parentNodeItem.alreadyUpdatedChildren = true; updatedParentTreeElements.push(parentNodeItem); } } for (var i = 0; i < updatedParentTreeElements.length; ++i) delete updatedParentTreeElements[i].alreadyUpdatedChildren; if (hidePanelWhileUpdating) { this._treeOutline.element.removeStyleClass("hidden"); if (originalScrollTop) treeOutlineContainerElement.scrollTop = originalScrollTop; this._treeOutline.updateSelection(); } this._recentlyModifiedNodes.clear(); }, _reset: function() { this._treeOutline.rootDOMNode = null; this._treeOutline.selectDOMNode(null, false); WebInspector.domAgent.hideDOMNodeHighlight(); this._recentlyModifiedNodes.clear(); } } WebInspector.ElementsTreeUpdater.UpdateEntry = function(isUpdated, parent) { this.isUpdated = isUpdated; if (parent) this.parent = parent; } WebInspector.DOMPresentationUtils = {} WebInspector.DOMPresentationUtils.decorateNodeLabel = function(node, parentElement) { var title = node.nodeNameInCorrectCase(); var nameElement = document.createElement("span"); nameElement.textContent = title; parentElement.appendChild(nameElement); var idAttribute = node.getAttribute("id"); if (idAttribute) { var idElement = document.createElement("span"); parentElement.appendChild(idElement); var part = "#" + idAttribute; title += part; idElement.appendChild(document.createTextNode(part)); nameElement.className = "extra"; } var classAttribute = node.getAttribute("class"); if (classAttribute) { var classes = classAttribute.split(/\s+/); var foundClasses = {}; if (classes.length) { var classesElement = document.createElement("span"); classesElement.className = "extra"; parentElement.appendChild(classesElement); for (var i = 0; i < classes.length; ++i) { var className = classes[i]; if (className && !(className in foundClasses)) { var part = "." + className; title += part; classesElement.appendChild(document.createTextNode(part)); foundClasses[className] = true; } } } } parentElement.title = title; } WebInspector.DOMPresentationUtils.linkifyNodeReference = function(node) { var link = document.createElement("span"); link.className = "node-link"; WebInspector.DOMPresentationUtils.decorateNodeLabel(node, link); link.addEventListener("click", WebInspector.domAgent.inspectElement.bind(WebInspector.domAgent, node.id), false); link.addEventListener("mouseover", WebInspector.domAgent.highlightDOMNode.bind(WebInspector.domAgent, node.id, ""), false); link.addEventListener("mouseout", WebInspector.domAgent.hideDOMNodeHighlight.bind(WebInspector.domAgent), false); return link; } WebInspector.DOMPresentationUtils.linkifyNodeById = function(nodeId) { var node = WebInspector.domAgent.nodeForId(nodeId); if (!node) return document.createTextNode(WebInspector.UIString("<node>")); return WebInspector.DOMPresentationUtils.linkifyNodeReference(node); } WebInspector.DOMPresentationUtils.buildImagePreviewContents = function(imageURL, showDimensions, userCallback, precomputedDimensions) { var resource = WebInspector.resourceTreeModel.resourceForURL(imageURL); if (!resource) { userCallback(); return; } var imageElement = document.createElement("img"); imageElement.addEventListener("load", buildContent, false); imageElement.addEventListener("error", errorCallback, false); resource.populateImageSource(imageElement); function errorCallback() { userCallback(); } function buildContent() { var container = document.createElement("table"); container.className = "image-preview-container"; var naturalWidth = precomputedDimensions ? precomputedDimensions.naturalWidth : imageElement.naturalWidth; var naturalHeight = precomputedDimensions ? precomputedDimensions.naturalHeight : imageElement.naturalHeight; var offsetWidth = precomputedDimensions ? precomputedDimensions.offsetWidth : naturalWidth; var offsetHeight = precomputedDimensions ? precomputedDimensions.offsetHeight : naturalHeight; var description; if (showDimensions) { if (offsetHeight === naturalHeight && offsetWidth === naturalWidth) description = WebInspector.UIString("%d \xd7 %d pixels", offsetWidth, offsetHeight); else description = WebInspector.UIString("%d \xd7 %d pixels (Natural: %d \xd7 %d pixels)", offsetWidth, offsetHeight, naturalWidth, naturalHeight); } container.createChild("tr").createChild("td", "image-container").appendChild(imageElement); if (description) container.createChild("tr").createChild("td").createChild("span", "description").textContent = description; userCallback(container); } } WebInspector.SidebarSectionTreeElement = function(title, representedObject, hasChildren) { TreeElement.call(this, title.escapeHTML(), representedObject || {}, hasChildren); this.expand(); } WebInspector.SidebarSectionTreeElement.prototype = { selectable: false, collapse: function() { }, get smallChildren() { return this._smallChildren; }, set smallChildren(x) { if (this._smallChildren === x) return; this._smallChildren = x; if (this._smallChildren) this._childrenListNode.addStyleClass("small"); else this._childrenListNode.removeStyleClass("small"); }, onattach: function() { this._listItemNode.addStyleClass("sidebar-tree-section"); }, onreveal: function() { if (this.listItemElement) this.listItemElement.scrollIntoViewIfNeeded(false); }, __proto__: TreeElement.prototype } WebInspector.SidebarTreeElement = function(className, title, subtitle, representedObject, hasChildren) { TreeElement.call(this, "", representedObject, hasChildren); if (hasChildren) { this.disclosureButton = document.createElement("button"); this.disclosureButton.className = "disclosure-button"; } if (!this.iconElement) { this.iconElement = document.createElement("img"); this.iconElement.className = "icon"; } this.statusElement = document.createElement("div"); this.statusElement.className = "status"; this.titlesElement = document.createElement("div"); this.titlesElement.className = "titles"; this.titleElement = document.createElement("span"); this.titleElement.className = "title"; this.titlesElement.appendChild(this.titleElement); this.subtitleElement = document.createElement("span"); this.subtitleElement.className = "subtitle"; this.titlesElement.appendChild(this.subtitleElement); this.className = className; this.mainTitle = title; this.subtitle = subtitle; } WebInspector.SidebarTreeElement.prototype = { get small() { return this._small; }, set small(x) { this._small = x; if (this._listItemNode) { if (this._small) this._listItemNode.addStyleClass("small"); else this._listItemNode.removeStyleClass("small"); } }, get mainTitle() { return this._mainTitle; }, set mainTitle(x) { this._mainTitle = x; this.refreshTitles(); }, get subtitle() { return this._subtitle; }, set subtitle(x) { this._subtitle = x; this.refreshTitles(); }, get bubbleText() { return this._bubbleText; }, set bubbleText(x) { if (!this.bubbleElement) { this.bubbleElement = document.createElement("div"); this.bubbleElement.className = "bubble"; this.statusElement.appendChild(this.bubbleElement); } this._bubbleText = x; this.bubbleElement.textContent = x; }, set wait(x) { if (x) this._listItemNode.addStyleClass("wait"); else this._listItemNode.removeStyleClass("wait"); }, refreshTitles: function() { var mainTitle = this.mainTitle; if (this.titleElement.textContent !== mainTitle) this.titleElement.textContent = mainTitle; var subtitle = this.subtitle; if (subtitle) { if (this.subtitleElement.textContent !== subtitle) this.subtitleElement.textContent = subtitle; this.titlesElement.removeStyleClass("no-subtitle"); } else { this.subtitleElement.textContent = ""; this.titlesElement.addStyleClass("no-subtitle"); } }, isEventWithinDisclosureTriangle: function(event) { return event.target === this.disclosureButton; }, onattach: function() { this._listItemNode.addStyleClass("sidebar-tree-item"); if (this.className) this._listItemNode.addStyleClass(this.className); if (this.small) this._listItemNode.addStyleClass("small"); if (this.hasChildren && this.disclosureButton) this._listItemNode.appendChild(this.disclosureButton); this._listItemNode.appendChild(this.iconElement); this._listItemNode.appendChild(this.statusElement); this._listItemNode.appendChild(this.titlesElement); }, onreveal: function() { if (this._listItemNode) this._listItemNode.scrollIntoViewIfNeeded(false); }, __proto__: TreeElement.prototype } WebInspector.Section = function(title, subtitle) { this.element = document.createElement("div"); this.element.className = "section"; this.element._section = this; this.headerElement = document.createElement("div"); this.headerElement.className = "header"; this.titleElement = document.createElement("div"); this.titleElement.className = "title"; this.subtitleElement = document.createElement("div"); this.subtitleElement.className = "subtitle"; this.headerElement.appendChild(this.subtitleElement); this.headerElement.appendChild(this.titleElement); this.headerElement.addEventListener("click", this.handleClick.bind(this), false); this.element.appendChild(this.headerElement); this.title = title; this.subtitle = subtitle; this._expanded = false; } WebInspector.Section.prototype = { get title() { return this._title; }, set title(x) { if (this._title === x) return; this._title = x; if (x instanceof Node) { this.titleElement.removeChildren(); this.titleElement.appendChild(x); } else this.titleElement.textContent = x; }, get subtitle() { return this._subtitle; }, set subtitle(x) { if (this._subtitle === x) return; this._subtitle = x; this.subtitleElement.textContent = x; }, get subtitleAsTextForTest() { var result = this.subtitleElement.textContent; var child = this.subtitleElement.querySelector("[data-uncopyable]"); if (child) { var linkData = child.getAttribute("data-uncopyable"); if (linkData) result += linkData; } return result; }, get expanded() { return this._expanded; }, set expanded(x) { if (x) this.expand(); else this.collapse(); }, get populated() { return this._populated; }, set populated(x) { this._populated = x; if (!x && this._expanded) { this.onpopulate(); this._populated = true; } }, onpopulate: function() { }, get firstSibling() { var parent = this.element.parentElement; if (!parent) return null; var childElement = parent.firstChild; while (childElement) { if (childElement._section) return childElement._section; childElement = childElement.nextSibling; } return null; }, get lastSibling() { var parent = this.element.parentElement; if (!parent) return null; var childElement = parent.lastChild; while (childElement) { if (childElement._section) return childElement._section; childElement = childElement.previousSibling; } return null; }, get nextSibling() { var curElement = this.element; do { curElement = curElement.nextSibling; } while (curElement && !curElement._section); return curElement ? curElement._section : null; }, get previousSibling() { var curElement = this.element; do { curElement = curElement.previousSibling; } while (curElement && !curElement._section); return curElement ? curElement._section : null; }, expand: function() { if (this._expanded) return; this._expanded = true; this.element.addStyleClass("expanded"); if (!this._populated) { this.onpopulate(); this._populated = true; } }, collapse: function() { if (!this._expanded) return; this._expanded = false; this.element.removeStyleClass("expanded"); }, toggleExpanded: function() { this.expanded = !this.expanded; }, handleClick: function(event) { this.toggleExpanded(); event.consume(); } } WebInspector.PropertiesSection = function(title, subtitle) { WebInspector.Section.call(this, title, subtitle); this.headerElement.addStyleClass("monospace"); this.propertiesElement = document.createElement("ol"); this.propertiesElement.className = "properties properties-tree monospace"; this.propertiesTreeOutline = new TreeOutline(this.propertiesElement, true); this.propertiesTreeOutline.setFocusable(false); this.propertiesTreeOutline.section = this; this.element.appendChild(this.propertiesElement); } WebInspector.PropertiesSection.prototype = { __proto__: WebInspector.Section.prototype } WebInspector.RemoteObject = function(objectId, type, subtype, value, description, preview) { this._type = type; this._subtype = subtype; if (objectId) { this._objectId = objectId; this._description = description; this._hasChildren = true; this._preview = preview; } else { console.assert(type !== "object" || value === null); this._description = description || (value + ""); this._hasChildren = false; this.value = value; } } WebInspector.RemoteObject.fromPrimitiveValue = function(value) { return new WebInspector.RemoteObject(undefined, typeof value, undefined, value); } WebInspector.RemoteObject.fromLocalObject = function(value) { return new WebInspector.LocalJSONObject(value); } WebInspector.RemoteObject.resolveNode = function(node, objectGroup, callback) { function mycallback(error, object) { if (!callback) return; if (error || !object) callback(null); else callback(WebInspector.RemoteObject.fromPayload(object)); } DOMAgent.resolveNode(node.id, objectGroup, mycallback); } WebInspector.RemoteObject.fromPayload = function(payload) { console.assert(typeof payload === "object", "Remote object payload should only be an object"); return new WebInspector.RemoteObject(payload.objectId, payload.type, payload.subtype, payload.value, payload.description, payload.preview); } WebInspector.RemoteObject.type = function(remoteObject) { if (remoteObject === null) return "null"; var type = typeof remoteObject; if (type !== "object" && type !== "function") return type; return remoteObject.type; } WebInspector.RemoteObject.prototype = { get objectId() { return this._objectId; }, get type() { return this._type; }, get subtype() { return this._subtype; }, get description() { return this._description; }, get hasChildren() { return this._hasChildren; }, get preview() { return this._preview; }, getOwnProperties: function(callback) { this._getProperties(true, callback); }, getAllProperties: function(callback) { this._getProperties(false, callback); }, _getProperties: function(ownProperties, callback) { if (!this._objectId) { callback([]); return; } function remoteObjectBinder(error, properties) { if (error) { callback(null); return; } var result = []; for (var i = 0; properties && i < properties.length; ++i) { var property = properties[i]; if (property.get || property.set) { if (property.get) result.push(new WebInspector.RemoteObjectProperty("get " + property.name, WebInspector.RemoteObject.fromPayload(property.get), property)); if (property.set) result.push(new WebInspector.RemoteObjectProperty("set " + property.name, WebInspector.RemoteObject.fromPayload(property.set), property)); } else result.push(new WebInspector.RemoteObjectProperty(property.name, WebInspector.RemoteObject.fromPayload(property.value), property)); } callback(result); } RuntimeAgent.getProperties(this._objectId, ownProperties, remoteObjectBinder); }, setPropertyValue: function(name, value, callback) { if (!this._objectId) { callback("Can't set a property of non-object."); return; } RuntimeAgent.evaluate.invoke({expression:value, doNotPauseOnExceptionsAndMuteConsole:true}, evaluatedCallback.bind(this)); function evaluatedCallback(error, result, wasThrown) { if (error || wasThrown) { callback(error || result.description); return; } var setPropertyValueFunction = "function(a, b) { this[a] = b; }"; if (result.type === "number" && typeof result.value !== "number") setPropertyValueFunction = "function(a) { this[a] = " + result.description + "; }"; delete result.description; RuntimeAgent.callFunctionOn(this._objectId, setPropertyValueFunction, [{ value:name }, result], true, undefined, undefined, propertySetCallback.bind(this)); if (result._objectId) RuntimeAgent.releaseObject(result._objectId); } function propertySetCallback(error, result, wasThrown) { if (error || wasThrown) { callback(error || result.description); return; } callback(); } }, pushNodeToFrontend: function(callback) { if (this._objectId) WebInspector.domAgent.pushNodeToFrontend(this._objectId, callback); else callback(0); }, callFunction: function(functionDeclaration, args, callback) { function mycallback(error, result, wasThrown) { if (!callback) return; callback((error || wasThrown) ? null : WebInspector.RemoteObject.fromPayload(result)); } RuntimeAgent.callFunctionOn(this._objectId, functionDeclaration.toString(), args, true, undefined, undefined, mycallback); }, callFunctionJSON: function(functionDeclaration, args, callback) { function mycallback(error, result, wasThrown) { callback((error || wasThrown) ? null : result.value); } RuntimeAgent.callFunctionOn(this._objectId, functionDeclaration.toString(), args, true, true, false, mycallback); }, release: function() { if (!this._objectId) return; RuntimeAgent.releaseObject(this._objectId); }, arrayLength: function() { if (this.subtype !== "array") return 0; var matches = this._description.match(/\[([0-9]+)\]/); if (!matches) return 0; return parseInt(matches[1], 10); } } WebInspector.RemoteObjectProperty = function(name, value, descriptor) { this.name = name; this.value = value; this.enumerable = descriptor ? !!descriptor.enumerable : true; this.writable = descriptor ? !!descriptor.writable : true; if (descriptor && descriptor.wasThrown) this.wasThrown = true; } WebInspector.RemoteObjectProperty.fromPrimitiveValue = function(name, value) { return new WebInspector.RemoteObjectProperty(name, WebInspector.RemoteObject.fromPrimitiveValue(value)); } WebInspector.RemoteObjectProperty.fromScopeValue = function(name, value) { var result = new WebInspector.RemoteObjectProperty(name, value); result.writable = false; return result; } WebInspector.LocalJSONObject = function(value) { this._value = value; } WebInspector.LocalJSONObject.prototype = { get description() { if (this._cachedDescription) return this._cachedDescription; if (this.type === "object") { switch (this.subtype) { case "array": function formatArrayItem(property) { return property.value.description; } this._cachedDescription = this._concatenate("[", "]", formatArrayItem); break; case "date": this._cachedDescription = "" + this._value; break; case "null": this._cachedDescription = "null"; break; default: function formatObjectItem(property) { return property.name + ":" + property.value.description; } this._cachedDescription = this._concatenate("{", "}", formatObjectItem); } } else this._cachedDescription = String(this._value); return this._cachedDescription; }, _concatenate: function(prefix, suffix, formatProperty) { const previewChars = 100; var buffer = prefix; var children = this._children(); for (var i = 0; i < children.length; ++i) { var itemDescription = formatProperty(children[i]); if (buffer.length + itemDescription.length > previewChars) { buffer += ",\u2026"; break; } if (i) buffer += ", "; buffer += itemDescription; } buffer += suffix; return buffer; }, get type() { return typeof this._value; }, get subtype() { if (this._value === null) return "null"; if (this._value instanceof Array) return "array"; if (this._value instanceof Date) return "date"; return undefined; }, get hasChildren() { return typeof this._value === "object" && this._value !== null && !!Object.keys(this._value).length; }, getOwnProperties: function(callback) { callback(this._children()); }, getAllProperties: function(callback) { callback(this._children()); }, _children: function() { if (!this.hasChildren) return []; function buildProperty(propName) { return new WebInspector.RemoteObjectProperty(propName, new WebInspector.LocalJSONObject(this._value[propName])); } if (!this._cachedChildren) this._cachedChildren = Object.keys(this._value || {}).map(buildProperty.bind(this)); return this._cachedChildren; }, isError: function() { return false; }, arrayLength: function() { return this._value instanceof Array ? this._value.length : 0; } } WebInspector.ObjectPropertiesSection = function(object, title, subtitle, emptyPlaceholder, ignoreHasOwnProperty, extraProperties, treeElementConstructor) { this.emptyPlaceholder = (emptyPlaceholder || WebInspector.UIString("No Properties")); this.object = object; this.ignoreHasOwnProperty = ignoreHasOwnProperty; this.extraProperties = extraProperties; this.treeElementConstructor = treeElementConstructor || WebInspector.ObjectPropertyTreeElement; this.editable = true; this.skipProto = false; WebInspector.PropertiesSection.call(this, title || "", subtitle); } WebInspector.ObjectPropertiesSection._arrayLoadThreshold = 100; WebInspector.ObjectPropertiesSection.prototype = { enableContextMenu: function() { this.element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true); }, _contextMenuEventFired: function(event) { var contextMenu = new WebInspector.ContextMenu(event); contextMenu.appendApplicableItems(this.object); contextMenu.show(); }, onpopulate: function() { this.update(); }, update: function() { if (this.object.arrayLength() > WebInspector.ObjectPropertiesSection._arrayLoadThreshold) { this.propertiesTreeOutline.removeChildren(); WebInspector.ArrayGroupingTreeElement._populateArray(this.propertiesTreeOutline, this.object, 0, this.object.arrayLength() - 1); return; } function callback(properties) { if (!properties) return; this.updateProperties(properties); } if (this.ignoreHasOwnProperty) this.object.getAllProperties(callback.bind(this)); else this.object.getOwnProperties(callback.bind(this)); }, updateProperties: function(properties, rootTreeElementConstructor, rootPropertyComparer) { if (!rootTreeElementConstructor) rootTreeElementConstructor = this.treeElementConstructor; if (!rootPropertyComparer) rootPropertyComparer = WebInspector.ObjectPropertiesSection.CompareProperties; if (this.extraProperties) for (var i = 0; i < this.extraProperties.length; ++i) properties.push(this.extraProperties[i]); properties.sort(rootPropertyComparer); this.propertiesTreeOutline.removeChildren(); for (var i = 0; i < properties.length; ++i) { if (this.skipProto && properties[i].name === "__proto__") continue; properties[i].parentObject = this.object; } this.propertiesForTest = properties; for (var i = 0; i < properties.length; ++i) this.propertiesTreeOutline.appendChild(new rootTreeElementConstructor(properties[i])); if (!this.propertiesTreeOutline.children.length) { var title = document.createElement("div"); title.className = "info"; title.textContent = this.emptyPlaceholder; var infoElement = new TreeElement(title, null, false); this.propertiesTreeOutline.appendChild(infoElement); } }, __proto__: WebInspector.PropertiesSection.prototype } WebInspector.ObjectPropertiesSection.CompareProperties = function(propertyA, propertyB) { var a = propertyA.name; var b = propertyB.name; if (a === "__proto__") return 1; if (b === "__proto__") return -1; var diff = 0; var chunk = /^\d+|^\D+/; var chunka, chunkb, anum, bnum; while (diff === 0) { if (!a && b) return -1; if (!b && a) return 1; chunka = a.match(chunk)[0]; chunkb = b.match(chunk)[0]; anum = !isNaN(chunka); bnum = !isNaN(chunkb); if (anum && !bnum) return -1; if (bnum && !anum) return 1; if (anum && bnum) { diff = chunka - chunkb; if (diff === 0 && chunka.length !== chunkb.length) { if (!+chunka && !+chunkb) return chunka.length - chunkb.length; else return chunkb.length - chunka.length; } } else if (chunka !== chunkb) return (chunka < chunkb) ? -1 : 1; a = a.substring(chunka.length); b = b.substring(chunkb.length); } return diff; } WebInspector.ObjectPropertyTreeElement = function(property) { this.property = property; TreeElement.call(this, "", null, false); this.toggleOnClick = true; this.selectable = false; } WebInspector.ObjectPropertyTreeElement.prototype = { onpopulate: function() { return WebInspector.ObjectPropertyTreeElement.populate(this, this.property.value); }, ondblclick: function(event) { if (this.property.writable) this.startEditing(event); }, onattach: function() { this.update(); }, update: function() { this.nameElement = document.createElement("span"); this.nameElement.className = "name"; this.nameElement.textContent = this.property.name; if (!this.property.enumerable) this.nameElement.addStyleClass("dimmed"); var separatorElement = document.createElement("span"); separatorElement.className = "separator"; separatorElement.textContent = ": "; this.valueElement = document.createElement("span"); this.valueElement.className = "value"; var description = this.property.value.description; if (this.property.wasThrown) this.valueElement.textContent = "[Exception: " + description + "]"; else if (this.property.value.type === "string" && typeof description === "string") { this.valueElement.textContent = "\"" + description.replace(/\n/g, "\u21B5") + "\""; this.valueElement._originalTextContent = "\"" + description + "\""; } else if (this.property.value.type === "function" && typeof description === "string") { this.valueElement.textContent = /.*/.exec(description)[0].replace(/ +$/g, ""); this.valueElement._originalTextContent = description; } else this.valueElement.textContent = description; if (this.property.wasThrown) this.valueElement.addStyleClass("error"); if (this.property.value.subtype) this.valueElement.addStyleClass("console-formatted-" + this.property.value.subtype); else if (this.property.value.type) this.valueElement.addStyleClass("console-formatted-" + this.property.value.type); this.valueElement.addEventListener("contextmenu", this._contextMenuFired.bind(this, this.property.value), false); this.valueElement.title = description || ""; this.listItemElement.removeChildren(); this.listItemElement.appendChild(this.nameElement); this.listItemElement.appendChild(separatorElement); this.listItemElement.appendChild(this.valueElement); this.hasChildren = this.property.value.hasChildren && !this.property.wasThrown; }, _contextMenuFired: function(value, event) { var contextMenu = new WebInspector.ContextMenu(event); this.populateContextMenu(contextMenu); contextMenu.appendApplicableItems(value); contextMenu.show(); }, populateContextMenu: function(contextMenu) { }, updateSiblings: function() { if (this.parent.root) this.treeOutline.section.update(); else this.parent.shouldRefreshChildren = true; }, renderPromptAsBlock: function() { return false; }, elementAndValueToEdit: function(event) { return [this.valueElement, (typeof this.valueElement._originalTextContent === "string") ? this.valueElement._originalTextContent : undefined]; }, startEditing: function(event) { var elementAndValueToEdit = this.elementAndValueToEdit(event); var elementToEdit = elementAndValueToEdit[0]; var valueToEdit = elementAndValueToEdit[1]; if (WebInspector.isBeingEdited(elementToEdit) || !this.treeOutline.section.editable || this._readOnly) return; if (typeof valueToEdit !== "undefined") elementToEdit.textContent = valueToEdit; var context = { expanded: this.expanded, elementToEdit: elementToEdit, previousContent: elementToEdit.textContent }; this.hasChildren = false; this.listItemElement.addStyleClass("editing-sub-part"); this._prompt = new WebInspector.ObjectPropertyPrompt(this.editingCommitted.bind(this, null, elementToEdit.textContent, context.previousContent, context), this.editingCancelled.bind(this, null, context), this.renderPromptAsBlock()); function blurListener() { this.editingCommitted(null, elementToEdit.textContent, context.previousContent, context); } var proxyElement = this._prompt.attachAndStartEditing(elementToEdit, blurListener.bind(this)); window.getSelection().setBaseAndExtent(elementToEdit, 0, elementToEdit, 1); proxyElement.addEventListener("keydown", this._promptKeyDown.bind(this, context), false); }, isEditing: function() { return !!this._prompt; }, editingEnded: function(context) { this._prompt.detach(); delete this._prompt; this.listItemElement.scrollLeft = 0; this.listItemElement.removeStyleClass("editing-sub-part"); if (context.expanded) this.expand(); }, editingCancelled: function(element, context) { this.editingEnded(context); this.update(); }, editingCommitted: function(element, userInput, previousContent, context) { if (userInput === previousContent) return this.editingCancelled(element, context); this.editingEnded(context); this.applyExpression(userInput, true); }, _promptKeyDown: function(context, event) { if (isEnterKey(event)) { event.consume(true); return this.editingCommitted(null, context.elementToEdit.textContent, context.previousContent, context); } if (event.keyIdentifier === "U+001B") { event.consume(); return this.editingCancelled(null, context); } }, applyExpression: function(expression, updateInterface) { expression = expression.trim(); var expressionLength = expression.length; function callback(error) { if (!updateInterface) return; if (error) this.update(); if (!expressionLength) { this.parent.removeChild(this); } else { this.updateSiblings(); } }; this.property.parentObject.setPropertyValue(this.property.name, expression.trim(), callback.bind(this)); }, propertyPath: function() { if ("_cachedPropertyPath" in this) return this._cachedPropertyPath; var current = this; var result; do { if (current.property) { if (result) result = current.property.name + "." + result; else result = current.property.name; } current = current.parent; } while (current && !current.root); this._cachedPropertyPath = result; return result; }, __proto__: TreeElement.prototype } WebInspector.ObjectPropertyTreeElement.populate = function(treeElement, value) { if (treeElement.children.length && !treeElement.shouldRefreshChildren) return; if (value.arrayLength() > WebInspector.ObjectPropertiesSection._arrayLoadThreshold) { treeElement.removeChildren(); WebInspector.ArrayGroupingTreeElement._populateArray(treeElement, value, 0, value.arrayLength() - 1); return; } function callback(properties) { treeElement.removeChildren(); if (!properties) return; properties.sort(WebInspector.ObjectPropertiesSection.CompareProperties); for (var i = 0; i < properties.length; ++i) { if (treeElement.treeOutline.section.skipProto && properties[i].name === "__proto__") continue; properties[i].parentObject = value; treeElement.appendChild(new treeElement.treeOutline.section.treeElementConstructor(properties[i])); } if (value.type === "function") treeElement.appendChild(new WebInspector.FunctionScopeMainTreeElement(value)); } value.getOwnProperties(callback); } WebInspector.FunctionScopeMainTreeElement = function(remoteObject) { TreeElement.call(this, "<function scope>", null, false); this.toggleOnClick = true; this.selectable = false; this._remoteObject = remoteObject; this.hasChildren = true; } WebInspector.FunctionScopeMainTreeElement.prototype = { onpopulate: function() { if (this.children.length && !this.shouldRefreshChildren) return; function didGetDetails(error, response) { if (error) { console.error(error); return; } this.removeChildren(); var scopeChain = response.scopeChain; if (!scopeChain) return; for (var i = 0; i < scopeChain.length; ++i) { var scope = scopeChain[i]; var title = null; var isTrueObject; switch (scope.type) { case "local": title = WebInspector.UIString("Local"); isTrueObject = false; break; case "closure": title = WebInspector.UIString("Closure"); isTrueObject = false; break; case "catch": title = WebInspector.UIString("Catch"); isTrueObject = false; break; case "with": title = WebInspector.UIString("With Block"); isTrueObject = true; break; case "global": title = WebInspector.UIString("Global"); isTrueObject = true; break; } var remoteObject = WebInspector.RemoteObject.fromPayload(scope.object); if (isTrueObject) { var property = WebInspector.RemoteObjectProperty.fromScopeValue(title, remoteObject); property.parentObject = null; this.appendChild(new this.treeOutline.section.treeElementConstructor(property)); } else { var scopeTreeElement = new WebInspector.ScopeTreeElement(title, null, remoteObject); this.appendChild(scopeTreeElement); } } } DebuggerAgent.getFunctionDetails(this._remoteObject.objectId, didGetDetails.bind(this)); }, __proto__: TreeElement.prototype } WebInspector.ScopeTreeElement = function(title, subtitle, remoteObject) { TreeElement.call(this, title, null, false); this.toggleOnClick = true; this.selectable = false; this._remoteObject = remoteObject; this.hasChildren = true; } WebInspector.ScopeTreeElement.prototype = { onpopulate: function() { return WebInspector.ObjectPropertyTreeElement.populate(this, this._remoteObject); }, __proto__: TreeElement.prototype } WebInspector.ArrayGroupingTreeElement = function(object, fromIndex, toIndex, propertyCount) { TreeElement.call(this, String.sprintf("[%d \u2026 %d]", fromIndex, toIndex), undefined, true); this._fromIndex = fromIndex; this._toIndex = toIndex; this._object = object; this._readOnly = true; this._propertyCount = propertyCount; this._populated = false; } WebInspector.ArrayGroupingTreeElement._bucketThreshold = 100; WebInspector.ArrayGroupingTreeElement._populateArray = function(treeElement, object, fromIndex, toIndex) { WebInspector.ArrayGroupingTreeElement._populateRanges(treeElement, object, fromIndex, toIndex, true); } WebInspector.ArrayGroupingTreeElement._populateRanges = function(treeElement, object, fromIndex, toIndex, topLevel) { object.callFunctionJSON(packRanges, [{value: fromIndex}, {value: toIndex}, {value: WebInspector.ArrayGroupingTreeElement._bucketThreshold}], callback.bind(this)); function packRanges(fromIndex, toIndex, bucketThreshold) { var count = 0; for (var i = fromIndex; i <= toIndex; ++i) { if (i in this) ++count; } var bucketSize = count; if (count <= bucketThreshold) bucketSize = count; else bucketSize = Math.pow(bucketThreshold, Math.ceil(Math.log(count) / Math.log(bucketThreshold)) - 1); var ranges = []; count = 0; var groupStart = -1; var groupEnd = 0; for (var i = fromIndex; i <= toIndex; ++i) { if (!(i in this)) continue; if (groupStart === -1) groupStart = i; groupEnd = i; if (++count === bucketSize) { ranges.push([groupStart, groupEnd, count]); count = 0; groupStart = -1; } } if (count > 0) ranges.push([groupStart, groupEnd, count]); return ranges; } function callback(ranges) { if (ranges.length == 1) WebInspector.ArrayGroupingTreeElement._populateAsFragment(treeElement, object, ranges[0][0], ranges[0][1]); else { for (var i = 0; i < ranges.length; ++i) { var fromIndex = ranges[i][0]; var toIndex = ranges[i][1]; var count = ranges[i][2]; if (fromIndex == toIndex) WebInspector.ArrayGroupingTreeElement._populateAsFragment(treeElement, object, fromIndex, toIndex); else treeElement.appendChild(new WebInspector.ArrayGroupingTreeElement(object, fromIndex, toIndex, count)); } } if (topLevel) WebInspector.ArrayGroupingTreeElement._populateNonIndexProperties(treeElement, object); } } WebInspector.ArrayGroupingTreeElement._populateAsFragment = function(treeElement, object, fromIndex, toIndex) { object.callFunction(buildArrayFragment, [{value: fromIndex}, {value: toIndex}], processArrayFragment.bind(this)); function buildArrayFragment(fromIndex, toIndex) { var result = Object.create(null); for (var i = fromIndex; i <= toIndex; ++i) { if (i in this) result[i] = this[i]; } return result; } function processArrayFragment(arrayFragment) { arrayFragment.getAllProperties(processProperties.bind(this)); } function processProperties(properties) { if (!properties) return; properties.sort(WebInspector.ObjectPropertiesSection.CompareProperties); for (var i = 0; i < properties.length; ++i) { properties[i].parentObject = this._object; var childTreeElement = new treeElement.treeOutline.section.treeElementConstructor(properties[i]); childTreeElement._readOnly = true; treeElement.appendChild(childTreeElement); } } } WebInspector.ArrayGroupingTreeElement._populateNonIndexProperties = function(treeElement, object) { object.callFunction(buildObjectFragment, undefined, processObjectFragment.bind(this)); function buildObjectFragment() { var result = Object.create(this.__proto__); var names = Object.getOwnPropertyNames(this); for (var i = 0; i < names.length; ++i) { var name = names[i]; if (!isNaN(name)) continue; var descriptor = Object.getOwnPropertyDescriptor(this, name); if (descriptor) Object.defineProperty(result, name, descriptor); } return result; } function processObjectFragment(arrayFragment) { arrayFragment.getOwnProperties(processProperties.bind(this)); } function processProperties(properties) { if (!properties) return; properties.sort(WebInspector.ObjectPropertiesSection.CompareProperties); for (var i = 0; i < properties.length; ++i) { properties[i].parentObject = this._object; var childTreeElement = new treeElement.treeOutline.section.treeElementConstructor(properties[i]); childTreeElement._readOnly = true; treeElement.appendChild(childTreeElement); } } } WebInspector.ArrayGroupingTreeElement.prototype = { onpopulate: function() { if (this._populated) return; this._populated = true; if (this._propertyCount >= WebInspector.ArrayGroupingTreeElement._bucketThreshold) { WebInspector.ArrayGroupingTreeElement._populateRanges(this, this._object, this._fromIndex, this._toIndex, false); return; } WebInspector.ArrayGroupingTreeElement._populateAsFragment(this, this._object, this._fromIndex, this._toIndex); }, onattach: function() { this.listItemElement.addStyleClass("name"); }, __proto__: TreeElement.prototype } WebInspector.ObjectPropertyPrompt = function(commitHandler, cancelHandler, renderAsBlock) { WebInspector.TextPrompt.call(this, WebInspector.runtimeModel.completionsForTextPrompt.bind(WebInspector.runtimeModel)); this.setSuggestBoxEnabled("generic-suggest"); if (renderAsBlock) this.renderAsBlock(); } WebInspector.ObjectPropertyPrompt.prototype = { __proto__: WebInspector.TextPrompt.prototype } WebInspector.ObjectPopoverHelper = function(panelElement, getAnchor, queryObject, onHide, disableOnClick) { WebInspector.PopoverHelper.call(this, panelElement, getAnchor, this._showObjectPopover.bind(this), this._onHideObjectPopover.bind(this), disableOnClick); this._queryObject = queryObject; this._onHideCallback = onHide; this._popoverObjectGroup = "popover"; panelElement.addEventListener("scroll", this.hidePopover.bind(this), true); }; WebInspector.ObjectPopoverHelper.prototype = { _showObjectPopover: function(element, popover) { function showObjectPopover(result, wasThrown, anchorOverride) { if (popover.disposed) return; if (wasThrown) { this.hidePopover(); return; } var anchorElement = anchorOverride || element; var popoverContentElement = null; if (result.type !== "object") { popoverContentElement = document.createElement("span"); popoverContentElement.className = "monospace console-formatted-" + result.type; popoverContentElement.style.whiteSpace = "pre"; popoverContentElement.textContent = result.description; if (result.type === "function") { function didGetDetails(error, response) { if (error) { console.error(error); return; } var container = document.createElement("div"); container.style.display = "inline-block"; var title = container.createChild("div", "function-popover-title source-code"); var functionName = title.createChild("span", "function-name"); functionName.textContent = response.name || response.inferredName || response.displayName || WebInspector.UIString("(anonymous function)"); this._linkifier = new WebInspector.Linkifier(); var rawLocation = (response.location); var link = this._linkifier.linkifyRawLocation(rawLocation, "function-location-link"); if (link) title.appendChild(link); container.appendChild(popoverContentElement); popover.show(container, anchorElement); } DebuggerAgent.getFunctionDetails(result.objectId, didGetDetails.bind(this)); return; } if (result.type === "string") popoverContentElement.textContent = "\"" + popoverContentElement.textContent + "\""; popover.show(popoverContentElement, anchorElement); } else { popoverContentElement = document.createElement("div"); this._titleElement = document.createElement("div"); this._titleElement.className = "source-frame-popover-title monospace"; this._titleElement.textContent = result.description; popoverContentElement.appendChild(this._titleElement); var section = new WebInspector.ObjectPropertiesSection(result); if (result.description.substr(0, 4) === "HTML") { this._sectionUpdateProperties = section.updateProperties.bind(section); section.updateProperties = this._updateHTMLId.bind(this); } section.expanded = true; section.element.addStyleClass("source-frame-popover-tree"); section.headerElement.addStyleClass("hidden"); popoverContentElement.appendChild(section.element); const popoverWidth = 300; const popoverHeight = 250; popover.show(popoverContentElement, anchorElement, popoverWidth, popoverHeight); } } this._queryObject(element, showObjectPopover.bind(this), this._popoverObjectGroup); }, _onHideObjectPopover: function() { if (this._linkifier) { this._linkifier.reset(); delete this._linkifier; } if (this._onHideCallback) this._onHideCallback(); RuntimeAgent.releaseObjectGroup(this._popoverObjectGroup); }, _updateHTMLId: function(properties, rootTreeElementConstructor, rootPropertyComparer) { for (var i = 0; i < properties.length; ++i) { if (properties[i].name === "id") { if (properties[i].value.description) this._titleElement.textContent += "#" + properties[i].value.description; break; } } this._sectionUpdateProperties(properties, rootTreeElementConstructor, rootPropertyComparer); }, __proto__: WebInspector.PopoverHelper.prototype } WebInspector.NativeBreakpointsSidebarPane = function(title) { WebInspector.SidebarPane.call(this, title); this.listElement = document.createElement("ol"); this.listElement.className = "breakpoint-list"; this.emptyElement = document.createElement("div"); this.emptyElement.className = "info"; this.emptyElement.textContent = WebInspector.UIString("No Breakpoints"); this.bodyElement.appendChild(this.emptyElement); } WebInspector.NativeBreakpointsSidebarPane.prototype = { _addListElement: function(element, beforeElement) { if (beforeElement) this.listElement.insertBefore(element, beforeElement); else { if (!this.listElement.firstChild) { this.bodyElement.removeChild(this.emptyElement); this.bodyElement.appendChild(this.listElement); } this.listElement.appendChild(element); } }, _removeListElement: function(element) { this.listElement.removeChild(element); if (!this.listElement.firstChild) { this.bodyElement.removeChild(this.listElement); this.bodyElement.appendChild(this.emptyElement); } }, _reset: function() { this.listElement.removeChildren(); if (this.listElement.parentElement) { this.bodyElement.removeChild(this.listElement); this.bodyElement.appendChild(this.emptyElement); } }, __proto__: WebInspector.SidebarPane.prototype } WebInspector.DOMBreakpointsSidebarPane = function() { WebInspector.NativeBreakpointsSidebarPane.call(this, WebInspector.UIString("DOM Breakpoints")); this._breakpointElements = {}; this._breakpointTypes = { SubtreeModified: "subtree-modified", AttributeModified: "attribute-modified", NodeRemoved: "node-removed" }; this._breakpointTypeLabels = {}; this._breakpointTypeLabels[this._breakpointTypes.SubtreeModified] = WebInspector.UIString("Subtree Modified"); this._breakpointTypeLabels[this._breakpointTypes.AttributeModified] = WebInspector.UIString("Attribute Modified"); this._breakpointTypeLabels[this._breakpointTypes.NodeRemoved] = WebInspector.UIString("Node Removed"); this._contextMenuLabels = {}; this._contextMenuLabels[this._breakpointTypes.SubtreeModified] = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Subtree modifications" : "Subtree Modifications"); this._contextMenuLabels[this._breakpointTypes.AttributeModified] = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Attributes modifications" : "Attributes Modifications"); this._contextMenuLabels[this._breakpointTypes.NodeRemoved] = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Node removal" : "Node Removal"); WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged, this._inspectedURLChanged, this); WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.NodeRemoved, this._nodeRemoved, this); } WebInspector.DOMBreakpointsSidebarPane.prototype = { _inspectedURLChanged: function(event) { this._breakpointElements = {}; this._reset(); var url = event.data; this._inspectedURL = url.removeURLFragment(); }, populateNodeContextMenu: function(node, contextMenu) { var nodeBreakpoints = {}; for (var id in this._breakpointElements) { var element = this._breakpointElements[id]; if (element._node === node) nodeBreakpoints[element._type] = true; } function toggleBreakpoint(type) { if (!nodeBreakpoints[type]) this._setBreakpoint(node, type, true); else this._removeBreakpoint(node, type); this._saveBreakpoints(); } var breakPointSubMenu = contextMenu.appendSubMenuItem(WebInspector.UIString("Break on...")); for (var key in this._breakpointTypes) { var type = this._breakpointTypes[key]; var label = this._contextMenuLabels[type]; breakPointSubMenu.appendCheckboxItem(label, toggleBreakpoint.bind(this, type), nodeBreakpoints[type]); } }, createBreakpointHitStatusMessage: function(auxData, callback) { if (auxData.type === this._breakpointTypes.SubtreeModified) { var targetNodeObject = WebInspector.RemoteObject.fromPayload(auxData["targetNode"]); function didPushNodeToFrontend(targetNodeId) { if (targetNodeId) targetNodeObject.release(); this._doCreateBreakpointHitStatusMessage(auxData, targetNodeId, callback); } targetNodeObject.pushNodeToFrontend(didPushNodeToFrontend.bind(this)); } else this._doCreateBreakpointHitStatusMessage(auxData, null, callback); }, _doCreateBreakpointHitStatusMessage: function (auxData, targetNodeId, callback) { var message; var typeLabel = this._breakpointTypeLabels[auxData.type]; var linkifiedNode = WebInspector.DOMPresentationUtils.linkifyNodeById(auxData.nodeId); var substitutions = [typeLabel, linkifiedNode]; var targetNode = ""; if (targetNodeId) targetNode = WebInspector.DOMPresentationUtils.linkifyNodeById(targetNodeId); if (auxData.type === this._breakpointTypes.SubtreeModified) { if (auxData.insertion) { if (targetNodeId !== auxData.nodeId) { message = "Paused on a \"%s\" breakpoint set on %s, because a new child was added to its descendant %s."; substitutions.push(targetNode); } else message = "Paused on a \"%s\" breakpoint set on %s, because a new child was added to that node."; } else { message = "Paused on a \"%s\" breakpoint set on %s, because its descendant %s was removed."; substitutions.push(targetNode); } } else message = "Paused on a \"%s\" breakpoint set on %s."; var element = document.createElement("span"); var formatters = { s: function(substitution) { return substitution; } }; function append(a, b) { if (typeof b === "string") b = document.createTextNode(b); element.appendChild(b); } WebInspector.formatLocalized(message, substitutions, formatters, "", append); callback(element); }, _nodeRemoved: function(event) { var node = event.data.node; this._removeBreakpointsForNode(event.data.node); if (!node.children) return; for (var i = 0; i < node.children.length; ++i) this._removeBreakpointsForNode(node.children[i]); this._saveBreakpoints(); }, _removeBreakpointsForNode: function(node) { for (var id in this._breakpointElements) { var element = this._breakpointElements[id]; if (element._node === node) this._removeBreakpoint(element._node, element._type); } }, _setBreakpoint: function(node, type, enabled) { var breakpointId = this._createBreakpointId(node.id, type); if (breakpointId in this._breakpointElements) return; var element = document.createElement("li"); element._node = node; element._type = type; element.addEventListener("contextmenu", this._contextMenu.bind(this, node, type), true); var checkboxElement = document.createElement("input"); checkboxElement.className = "checkbox-elem"; checkboxElement.type = "checkbox"; checkboxElement.checked = enabled; checkboxElement.addEventListener("click", this._checkboxClicked.bind(this, node, type), false); element._checkboxElement = checkboxElement; element.appendChild(checkboxElement); var labelElement = document.createElement("span"); element.appendChild(labelElement); var linkifiedNode = WebInspector.DOMPresentationUtils.linkifyNodeById(node.id); linkifiedNode.addStyleClass("monospace"); labelElement.appendChild(linkifiedNode); var description = document.createElement("div"); description.className = "source-text"; description.textContent = this._breakpointTypeLabels[type]; labelElement.appendChild(description); var currentElement = this.listElement.firstChild; while (currentElement) { if (currentElement._type && currentElement._type < element._type) break; currentElement = currentElement.nextSibling; } this._addListElement(element, currentElement); this._breakpointElements[breakpointId] = element; if (enabled) DOMDebuggerAgent.setDOMBreakpoint(node.id, type); }, _removeAllBreakpoints: function() { for (var id in this._breakpointElements) { var element = this._breakpointElements[id]; this._removeBreakpoint(element._node, element._type); } this._saveBreakpoints(); }, _removeBreakpoint: function(node, type) { var breakpointId = this._createBreakpointId(node.id, type); var element = this._breakpointElements[breakpointId]; if (!element) return; this._removeListElement(element); delete this._breakpointElements[breakpointId]; if (element._checkboxElement.checked) DOMDebuggerAgent.removeDOMBreakpoint(node.id, type); }, _contextMenu: function(node, type, event) { var contextMenu = new WebInspector.ContextMenu(event); function removeBreakpoint() { this._removeBreakpoint(node, type); this._saveBreakpoints(); } contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), removeBreakpoint.bind(this)); contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Remove all DOM breakpoints" : "Remove All DOM Breakpoints"), this._removeAllBreakpoints.bind(this)); contextMenu.show(); }, _checkboxClicked: function(node, type, event) { if (event.target.checked) DOMDebuggerAgent.setDOMBreakpoint(node.id, type); else DOMDebuggerAgent.removeDOMBreakpoint(node.id, type); this._saveBreakpoints(); }, highlightBreakpoint: function(auxData) { var breakpointId = this._createBreakpointId(auxData.nodeId, auxData.type); var element = this._breakpointElements[breakpointId]; if (!element) return; this.expanded = true; element.addStyleClass("breakpoint-hit"); this._highlightedElement = element; }, clearBreakpointHighlight: function() { if (this._highlightedElement) { this._highlightedElement.removeStyleClass("breakpoint-hit"); delete this._highlightedElement; } }, _createBreakpointId: function(nodeId, type) { return nodeId + ":" + type; }, _saveBreakpoints: function() { var breakpoints = []; var storedBreakpoints = WebInspector.settings.domBreakpoints.get(); for (var i = 0; i < storedBreakpoints.length; ++i) { var breakpoint = storedBreakpoints[i]; if (breakpoint.url !== this._inspectedURL) breakpoints.push(breakpoint); } for (var id in this._breakpointElements) { var element = this._breakpointElements[id]; breakpoints.push({ url: this._inspectedURL, path: element._node.path(), type: element._type, enabled: element._checkboxElement.checked }); } WebInspector.settings.domBreakpoints.set(breakpoints); }, restoreBreakpoints: function() { var pathToBreakpoints = {}; function didPushNodeByPathToFrontend(path, nodeId) { var node = WebInspector.domAgent.nodeForId(nodeId); if (!node) return; var breakpoints = pathToBreakpoints[path]; for (var i = 0; i < breakpoints.length; ++i) this._setBreakpoint(node, breakpoints[i].type, breakpoints[i].enabled); } var breakpoints = WebInspector.settings.domBreakpoints.get(); for (var i = 0; i < breakpoints.length; ++i) { var breakpoint = breakpoints[i]; if (breakpoint.url !== this._inspectedURL) continue; var path = breakpoint.path; if (!pathToBreakpoints[path]) { pathToBreakpoints[path] = []; WebInspector.domAgent.pushNodeByPathToFrontend(path, didPushNodeByPathToFrontend.bind(this, path)); } pathToBreakpoints[path].push(breakpoint); } }, __proto__: WebInspector.NativeBreakpointsSidebarPane.prototype } WebInspector.Color = function(str) { this.value = str; this._parse(); } WebInspector.Color.fromRGBA = function(r, g, b, a) { return new WebInspector.Color("rgba(" + r + "," + g + "," + b + "," + (typeof a === "undefined" ? 1 : a) + ")"); } WebInspector.Color.fromRGB = function(r, g, b) { return new WebInspector.Color("rgb(" + r + "," + g + "," + b + ")"); } WebInspector.Color.prototype = { get shorthex() { if ("_short" in this) return this._short; if (!this.simple) return ""; var hex = this.hex; if (hex.charAt(0) === hex.charAt(1) && hex.charAt(2) === hex.charAt(3) && hex.charAt(4) === hex.charAt(5)) this._short = hex.charAt(0) + hex.charAt(2) + hex.charAt(4); else this._short = hex; return this._short; }, get hex() { if (!this.simple) return ""; return this._hex; }, set hex(x) { this._hex = x; }, get rgb() { if (this._rgb) return this._rgb; if (this.simple) this._rgb = this._hexToRGB(this.hex); else { var rgba = this.rgba; this._rgb = [rgba[0], rgba[1], rgba[2]]; } return this._rgb; }, set rgb(x) { this._rgb = x; }, get hsl() { if (this._hsl) return this._hsl; this._hsl = this._rgbToHSL(this.rgb); return this._hsl; }, set hsl(x) { this._hsl = x; }, get nickname() { if (typeof this._nickname !== "undefined") return this._nickname; else return ""; }, set nickname(x) { this._nickname = x; }, get rgba() { return this._rgba; }, set rgba(x) { this._rgba = x; }, get hsla() { return this._hsla; }, set hsla(x) { this._hsla = x; }, hasShortHex: function() { var shorthex = this.shorthex; return (!!shorthex && shorthex.length === 3); }, toString: function(format) { if (!format) format = this.format; switch (format) { case "original": return this.value; case "rgb": return "rgb(" + this.rgb.join(", ") + ")"; case "rgba": return "rgba(" + this.rgba.join(", ") + ")"; case "hsl": var hsl = this.hsl; return "hsl(" + hsl[0] + ", " + hsl[1] + "%, " + hsl[2] + "%)"; case "hsla": var hsla = this.hsla; return "hsla(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%, " + hsla[3] + ")"; case "hex": return "#" + this.hex; case "shorthex": return "#" + this.shorthex; case "nickname": return this.nickname; } throw "invalid color format"; }, toProtocolRGBA: function() { if (this._protocolRGBA) return this._protocolRGBA; var components = this.rgba; if (components) this._protocolRGBA = { r: Number(components[0]), g: Number(components[1]), b: Number(components[2]), a: Number(components[3]) }; else { components = this.rgb; this._protocolRGBA = { r: Number(components[0]), g: Number(components[1]), b: Number(components[2]) }; } return this._protocolRGBA; }, _clamp: function(value, min, max) { if (value < min) return min; if (value > max) return max; return value; }, _individualRGBValueToFloatValue: function(rgbValue) { if (typeof rgbValue === "number") return this._clamp(rgbValue, 0, 255); if (rgbValue.indexOf("%") === -1) { var intValue = parseInt(rgbValue, 10); return this._clamp(intValue, 0, 255); } var percentValue = parseFloat(rgbValue); return this._clamp(percentValue, 0, 100) * 2.55; }, _individualRGBValueToHexValue: function(rgbValue) { var floatValue = this._individualRGBValueToFloatValue(rgbValue); var hex = Math.round(floatValue).toString(16); if (hex.length === 1) hex = "0" + hex; return hex; }, _rgbStringsToHex: function(rgb) { var r = this._individualRGBValueToHexValue(rgb[0]); var g = this._individualRGBValueToHexValue(rgb[1]); var b = this._individualRGBValueToHexValue(rgb[2]); return (r + g + b).toUpperCase(); }, _rgbToHex: function(rgb) { var r = this._individualRGBValueToHexValue(rgb[0]); var g = this._individualRGBValueToHexValue(rgb[1]); var b = this._individualRGBValueToHexValue(rgb[2]); return (r + g + b).toUpperCase(); }, _hexToRGB: function(hex) { var r = parseInt(hex.substring(0,2), 16); var g = parseInt(hex.substring(2,4), 16); var b = parseInt(hex.substring(4,6), 16); return [r, g, b]; }, _rgbToHSL: function(rgb) { var r = this._individualRGBValueToFloatValue(rgb[0]) / 255; var g = this._individualRGBValueToFloatValue(rgb[1]) / 255; var b = this._individualRGBValueToFloatValue(rgb[2]) / 255; var max = Math.max(r, g, b); var min = Math.min(r, g, b); var diff = max - min; var add = max + min; if (min === max) var h = 0; else if (r === max) var h = ((60 * (g - b) / diff) + 360) % 360; else if (g === max) var h = (60 * (b - r) / diff) + 120; else var h = (60 * (r - g) / diff) + 240; var l = 0.5 * add; if (l === 0) var s = 0; else if (l === 1) var s = 1; else if (l <= 0.5) var s = diff / add; else var s = diff / (2 - add); h = Math.round(h); s = Math.round(s*100); l = Math.round(l*100); return [h, s, l]; }, _hslToRGB: function(hsl) { var h = parseFloat(hsl[0]) / 360; var s = parseFloat(hsl[1]) / 100; var l = parseFloat(hsl[2]) / 100; if (s < 0) s = 0; if (l <= 0.5) var q = l * (1 + s); else var q = l + s - (l * s); var p = 2 * l - q; var tr = h + (1 / 3); var tg = h; var tb = h - (1 / 3); var r = Math.round(hueToRGB(p, q, tr) * 255); var g = Math.round(hueToRGB(p, q, tg) * 255); var b = Math.round(hueToRGB(p, q, tb) * 255); return [r, g, b]; function hueToRGB(p, q, h) { if (h < 0) h += 1; else if (h > 1) h -= 1; if ((h * 6) < 1) return p + (q - p) * h * 6; else if ((h * 2) < 1) return q; else if ((h * 3) < 2) return p + (q - p) * ((2 / 3) - h) * 6; else return p; } }, _rgbaToHSLA: function(rgba, alpha) { var hsl = this._rgbToHSL(rgba) hsl.push(alpha); return hsl; }, _hslaToRGBA: function(hsla, alpha) { var rgb = this._hslToRGB(hsla); rgb.push(alpha); return rgb; }, _parse: function() { var value = this.value.toLowerCase().replace(/%|\s+/g, ""); if (value in WebInspector.Color.AdvancedNickNames) { this.format = "nickname"; var set = WebInspector.Color.AdvancedNickNames[value]; this.simple = false; this.rgba = set[0]; this.hsla = set[1]; this.nickname = set[2]; this.alpha = set[0][3]; return; } var simple = /^(?:#([0-9a-f]{3,6})|rgb\(([^)]+)\)|(\w+)|hsl\(([^)]+)\))$/i; var match = this.value.match(simple); if (match) { this.simple = true; if (match[1]) { var hex = match[1].toUpperCase(); if (hex.length === 3) { this.format = "shorthex"; this.hex = hex.charAt(0) + hex.charAt(0) + hex.charAt(1) + hex.charAt(1) + hex.charAt(2) + hex.charAt(2); } else { this.format = "hex"; this.hex = hex; } } else if (match[2]) { this.format = "rgb"; var rgb = match[2].split(/\s*,\s*/); this.rgb = rgb; this.hex = this._rgbStringsToHex(rgb); } else if (match[3]) { var nickname = match[3].toLowerCase(); if (nickname in WebInspector.Color.Nicknames) { this.format = "nickname"; this.hex = WebInspector.Color.Nicknames[nickname]; } else throw "unknown color name"; } else if (match[4]) { this.format = "hsl"; var hsl = match[4].replace(/%/g, "").split(/\s*,\s*/); this.hsl = hsl; this.rgb = this._hslToRGB(hsl); this.hex = this._rgbToHex(this.rgb); } var hex = this.hex; if (hex && hex in WebInspector.Color.HexTable) { var set = WebInspector.Color.HexTable[hex]; this.rgb = set[0]; this.hsl = set[1]; this.nickname = set[2]; } return; } var advanced = /^(?:rgba\(([^)]+)\)|hsla\(([^)]+)\))$/; match = this.value.match(advanced); if (match) { this.simple = false; if (match[1]) { this.format = "rgba"; this.rgba = match[1].split(/\s*,\s*/); this.rgba[3] = this.alpha = this._clamp(this.rgba[3], 0, 1); this.hsla = this._rgbaToHSLA(this.rgba, this.alpha); } else if (match[2]) { this.format = "hsla"; this.hsla = match[2].replace(/%/g, "").split(/\s*,\s*/); this.hsla[3] = this.alpha = this._clamp(this.hsla[3], 0, 1); this.rgba = this._hslaToRGBA(this.hsla, this.alpha); } return; } throw "could not parse color"; } } WebInspector.Color.HexTable = { "000000": [[0, 0, 0], [0, 0, 0], "black"], "000080": [[0, 0, 128], [240, 100, 25], "navy"], "00008B": [[0, 0, 139], [240, 100, 27], "darkBlue"], "0000CD": [[0, 0, 205], [240, 100, 40], "mediumBlue"], "0000FF": [[0, 0, 255], [240, 100, 50], "blue"], "006400": [[0, 100, 0], [120, 100, 20], "darkGreen"], "008000": [[0, 128, 0], [120, 100, 25], "green"], "008080": [[0, 128, 128], [180, 100, 25], "teal"], "008B8B": [[0, 139, 139], [180, 100, 27], "darkCyan"], "00BFFF": [[0, 191, 255], [195, 100, 50], "deepSkyBlue"], "00CED1": [[0, 206, 209], [181, 100, 41], "darkTurquoise"], "00FA9A": [[0, 250, 154], [157, 100, 49], "mediumSpringGreen"], "00FF00": [[0, 255, 0], [120, 100, 50], "lime"], "00FF7F": [[0, 255, 127], [150, 100, 50], "springGreen"], "00FFFF": [[0, 255, 255], [180, 100, 50], "cyan"], "191970": [[25, 25, 112], [240, 64, 27], "midnightBlue"], "1E90FF": [[30, 144, 255], [210, 100, 56], "dodgerBlue"], "20B2AA": [[32, 178, 170], [177, 70, 41], "lightSeaGreen"], "228B22": [[34, 139, 34], [120, 61, 34], "forestGreen"], "2E8B57": [[46, 139, 87], [146, 50, 36], "seaGreen"], "2F4F4F": [[47, 79, 79], [180, 25, 25], "darkSlateGray"], "32CD32": [[50, 205, 50], [120, 61, 50], "limeGreen"], "3CB371": [[60, 179, 113], [147, 50, 47], "mediumSeaGreen"], "40E0D0": [[64, 224, 208], [174, 72, 56], "turquoise"], "4169E1": [[65, 105, 225], [225, 73, 57], "royalBlue"], "4682B4": [[70, 130, 180], [207, 44, 49], "steelBlue"], "483D8B": [[72, 61, 139], [248, 39, 39], "darkSlateBlue"], "48D1CC": [[72, 209, 204], [178, 60, 55], "mediumTurquoise"], "4B0082": [[75, 0, 130], [275, 100, 25], "indigo"], "556B2F": [[85, 107, 47], [82, 39, 30], "darkOliveGreen"], "5F9EA0": [[95, 158, 160], [182, 25, 50], "cadetBlue"], "6495ED": [[100, 149, 237], [219, 79, 66], "cornflowerBlue"], "66CDAA": [[102, 205, 170], [160, 51, 60], "mediumAquaMarine"], "696969": [[105, 105, 105], [0, 0, 41], "dimGray"], "6A5ACD": [[106, 90, 205], [248, 53, 58], "slateBlue"], "6B8E23": [[107, 142, 35], [80, 60, 35], "oliveDrab"], "708090": [[112, 128, 144], [210, 13, 50], "slateGray"], "778899": [[119, 136, 153], [210, 14, 53], "lightSlateGray"], "7B68EE": [[123, 104, 238], [249, 80, 67], "mediumSlateBlue"], "7CFC00": [[124, 252, 0], [90, 100, 49], "lawnGreen"], "7FFF00": [[127, 255, 0], [90, 100, 50], "chartreuse"], "7FFFD4": [[127, 255, 212], [160, 100, 75], "aquamarine"], "800000": [[128, 0, 0], [0, 100, 25], "maroon"], "800080": [[128, 0, 128], [300, 100, 25], "purple"], "808000": [[128, 128, 0], [60, 100, 25], "olive"], "808080": [[128, 128, 128], [0, 0, 50], "gray"], "87CEEB": [[135, 206, 235], [197, 71, 73], "skyBlue"], "87CEFA": [[135, 206, 250], [203, 92, 75], "lightSkyBlue"], "8A2BE2": [[138, 43, 226], [271, 76, 53], "blueViolet"], "8B0000": [[139, 0, 0], [0, 100, 27], "darkRed"], "8B008B": [[139, 0, 139], [300, 100, 27], "darkMagenta"], "8B4513": [[139, 69, 19], [25, 76, 31], "saddleBrown"], "8FBC8F": [[143, 188, 143], [120, 25, 65], "darkSeaGreen"], "90EE90": [[144, 238, 144], [120, 73, 75], "lightGreen"], "9370D8": [[147, 112, 219], [260, 60, 65], "mediumPurple"], "9400D3": [[148, 0, 211], [282, 100, 41], "darkViolet"], "98FB98": [[152, 251, 152], [120, 93, 79], "paleGreen"], "9932CC": [[153, 50, 204], [280, 61, 50], "darkOrchid"], "9ACD32": [[154, 205, 50], [80, 61, 50], "yellowGreen"], "A0522D": [[160, 82, 45], [19, 56, 40], "sienna"], "A52A2A": [[165, 42, 42], [0, 59, 41], "brown"], "A9A9A9": [[169, 169, 169], [0, 0, 66], "darkGray"], "ADD8E6": [[173, 216, 230], [195, 53, 79], "lightBlue"], "ADFF2F": [[173, 255, 47], [84, 100, 59], "greenYellow"], "AFEEEE": [[175, 238, 238], [180, 65, 81], "paleTurquoise"], "B0C4DE": [[176, 196, 222], [214, 41, 78], "lightSteelBlue"], "B0E0E6": [[176, 224, 230], [187, 52, 80], "powderBlue"], "B22222": [[178, 34, 34], [0, 68, 42], "fireBrick"], "B8860B": [[184, 134, 11], [43, 89, 38], "darkGoldenrod"], "BA55D3": [[186, 85, 211], [288, 59, 58], "mediumOrchid"], "BC8F8F": [[188, 143, 143], [0, 25, 65], "rosyBrown"], "BDB76B": [[189, 183, 107], [56, 38, 58], "darkKhaki"], "C0C0C0": [[192, 192, 192], [0, 0, 75], "silver"], "C71585": [[199, 21, 133], [322, 81, 43], "mediumVioletRed"], "CD5C5C": [[205, 92, 92], [0, 53, 58], "indianRed"], "CD853F": [[205, 133, 63], [30, 59, 53], "peru"], "D2691E": [[210, 105, 30], [25, 75, 47], "chocolate"], "D2B48C": [[210, 180, 140], [34, 44, 69], "tan"], "D3D3D3": [[211, 211, 211], [0, 0, 83], "lightGrey"], "D87093": [[219, 112, 147], [340, 60, 65], "paleVioletRed"], "D8BFD8": [[216, 191, 216], [300, 24, 80], "thistle"], "DA70D6": [[218, 112, 214], [302, 59, 65], "orchid"], "DAA520": [[218, 165, 32], [43, 74, 49], "goldenrod"], "DC143C": [[237, 164, 61], [35, 83, 58], "crimson"], "DCDCDC": [[220, 220, 220], [0, 0, 86], "gainsboro"], "DDA0DD": [[221, 160, 221], [300, 47, 75], "plum"], "DEB887": [[222, 184, 135], [34, 57, 70], "burlyWood"], "E0FFFF": [[224, 255, 255], [180, 100, 94], "lightCyan"], "E6E6FA": [[230, 230, 250], [240, 67, 94], "lavender"], "E9967A": [[233, 150, 122], [15, 72, 70], "darkSalmon"], "EE82EE": [[238, 130, 238], [300, 76, 72], "violet"], "EEE8AA": [[238, 232, 170], [55, 67, 80], "paleGoldenrod"], "F08080": [[240, 128, 128], [0, 79, 72], "lightCoral"], "F0E68C": [[240, 230, 140], [54, 77, 75], "khaki"], "F0F8FF": [[240, 248, 255], [208, 100, 97], "aliceBlue"], "F0FFF0": [[240, 255, 240], [120, 100, 97], "honeyDew"], "F0FFFF": [[240, 255, 255], [180, 100, 97], "azure"], "F4A460": [[244, 164, 96], [28, 87, 67], "sandyBrown"], "F5DEB3": [[245, 222, 179], [39, 77, 83], "wheat"], "F5F5DC": [[245, 245, 220], [60, 56, 91], "beige"], "F5F5F5": [[245, 245, 245], [0, 0, 96], "whiteSmoke"], "F5FFFA": [[245, 255, 250], [150, 100, 98], "mintCream"], "F8F8FF": [[248, 248, 255], [240, 100, 99], "ghostWhite"], "FA8072": [[250, 128, 114], [6, 93, 71], "salmon"], "FAEBD7": [[250, 235, 215], [34, 78, 91], "antiqueWhite"], "FAF0E6": [[250, 240, 230], [30, 67, 94], "linen"], "FAFAD2": [[250, 250, 210], [60, 80, 90], "lightGoldenrodYellow"], "FDF5E6": [[253, 245, 230], [39, 85, 95], "oldLace"], "FF0000": [[255, 0, 0], [0, 100, 50], "red"], "FF00FF": [[255, 0, 255], [300, 100, 50], "magenta"], "FF1493": [[255, 20, 147], [328, 100, 54], "deepPink"], "FF4500": [[255, 69, 0], [16, 100, 50], "orangeRed"], "FF6347": [[255, 99, 71], [9, 100, 64], "tomato"], "FF69B4": [[255, 105, 180], [330, 100, 71], "hotPink"], "FF7F50": [[255, 127, 80], [16, 100, 66], "coral"], "FF8C00": [[255, 140, 0], [33, 100, 50], "darkOrange"], "FFA07A": [[255, 160, 122], [17, 100, 74], "lightSalmon"], "FFA500": [[255, 165, 0], [39, 100, 50], "orange"], "FFB6C1": [[255, 182, 193], [351, 100, 86], "lightPink"], "FFC0CB": [[255, 192, 203], [350, 100, 88], "pink"], "FFD700": [[255, 215, 0], [51, 100, 50], "gold"], "FFDAB9": [[255, 218, 185], [28, 100, 86], "peachPuff"], "FFDEAD": [[255, 222, 173], [36, 100, 84], "navajoWhite"], "FFE4B5": [[255, 228, 181], [38, 100, 85], "moccasin"], "FFE4C4": [[255, 228, 196], [33, 100, 88], "bisque"], "FFE4E1": [[255, 228, 225], [6, 100, 94], "mistyRose"], "FFEBCD": [[255, 235, 205], [36, 100, 90], "blanchedAlmond"], "FFEFD5": [[255, 239, 213], [37, 100, 92], "papayaWhip"], "FFF0F5": [[255, 240, 245], [340, 100, 97], "lavenderBlush"], "FFF5EE": [[255, 245, 238], [25, 100, 97], "seaShell"], "FFF8DC": [[255, 248, 220], [48, 100, 93], "cornsilk"], "FFFACD": [[255, 250, 205], [54, 100, 90], "lemonChiffon"], "FFFAF0": [[255, 250, 240], [40, 100, 97], "floralWhite"], "FFFAFA": [[255, 250, 250], [0, 100, 99], "snow"], "FFFF00": [[255, 255, 0], [60, 100, 50], "yellow"], "FFFFE0": [[255, 255, 224], [60, 100, 94], "lightYellow"], "FFFFF0": [[255, 255, 240], [60, 100, 97], "ivory"], "FFFFFF": [[255, 255, 255], [0, 100, 100], "white"] }; WebInspector.Color.Nicknames = { "aliceblue": "F0F8FF", "antiquewhite": "FAEBD7", "aqua": "00FFFF", "aquamarine": "7FFFD4", "azure": "F0FFFF", "beige": "F5F5DC", "bisque": "FFE4C4", "black": "000000", "blanchedalmond": "FFEBCD", "blue": "0000FF", "blueviolet": "8A2BE2", "brown": "A52A2A", "burlywood": "DEB887", "cadetblue": "5F9EA0", "chartreuse": "7FFF00", "chocolate": "D2691E", "coral": "FF7F50", "cornflowerblue": "6495ED", "cornsilk": "FFF8DC", "crimson": "DC143C", "cyan": "00FFFF", "darkblue": "00008B", "darkcyan": "008B8B", "darkgoldenrod": "B8860B", "darkgray": "A9A9A9", "darkgreen": "006400", "darkkhaki": "BDB76B", "darkmagenta": "8B008B", "darkolivegreen": "556B2F", "darkorange": "FF8C00", "darkorchid": "9932CC", "darkred": "8B0000", "darksalmon": "E9967A", "darkseagreen": "8FBC8F", "darkslateblue": "483D8B", "darkslategray": "2F4F4F", "darkturquoise": "00CED1", "darkviolet": "9400D3", "deeppink": "FF1493", "deepskyblue": "00BFFF", "dimgray": "696969", "dodgerblue": "1E90FF", "firebrick": "B22222", "floralwhite": "FFFAF0", "forestgreen": "228B22", "fuchsia": "FF00FF", "gainsboro": "DCDCDC", "ghostwhite": "F8F8FF", "gold": "FFD700", "goldenrod": "DAA520", "gray": "808080", "green": "008000", "greenyellow": "ADFF2F", "honeydew": "F0FFF0", "hotpink": "FF69B4", "indianred": "CD5C5C", "indigo": "4B0082", "ivory": "FFFFF0", "khaki": "F0E68C", "lavender": "E6E6FA", "lavenderblush": "FFF0F5", "lawngreen": "7CFC00", "lemonchiffon": "FFFACD", "lightblue": "ADD8E6", "lightcoral": "F08080", "lightcyan": "E0FFFF", "lightgoldenrodyellow": "FAFAD2", "lightgreen": "90EE90", "lightgrey": "D3D3D3", "lightpink": "FFB6C1", "lightsalmon": "FFA07A", "lightseagreen": "20B2AA", "lightskyblue": "87CEFA", "lightslategray": "778899", "lightsteelblue": "B0C4DE", "lightyellow": "FFFFE0", "lime": "00FF00", "limegreen": "32CD32", "linen": "FAF0E6", "magenta": "FF00FF", "maroon": "800000", "mediumaquamarine": "66CDAA", "mediumblue": "0000CD", "mediumorchid": "BA55D3", "mediumpurple": "9370DB", "mediumseagreen": "3CB371", "mediumslateblue": "7B68EE", "mediumspringgreen": "00FA9A", "mediumturquoise": "48D1CC", "mediumvioletred": "C71585", "midnightblue": "191970", "mintcream": "F5FFFA", "mistyrose": "FFE4E1", "moccasin": "FFE4B5", "navajowhite": "FFDEAD", "navy": "000080", "oldlace": "FDF5E6", "olive": "808000", "olivedrab": "6B8E23", "orange": "FFA500", "orangered": "FF4500", "orchid": "DA70D6", "palegoldenrod": "EEE8AA", "palegreen": "98FB98", "paleturquoise": "AFEEEE", "palevioletred": "DB7093", "papayawhip": "FFEFD5", "peachpuff": "FFDAB9", "peru": "CD853F", "pink": "FFC0CB", "plum": "DDA0DD", "powderblue": "B0E0E6", "purple": "800080", "red": "FF0000", "rosybrown": "BC8F8F", "royalblue": "4169E1", "saddlebrown": "8B4513", "salmon": "FA8072", "sandybrown": "F4A460", "seagreen": "2E8B57", "seashell": "FFF5EE", "sienna": "A0522D", "silver": "C0C0C0", "skyblue": "87CEEB", "slateblue": "6A5ACD", "slategray": "708090", "snow": "FFFAFA", "springgreen": "00FF7F", "steelblue": "4682B4", "tan": "D2B48C", "teal": "008080", "thistle": "D8BFD8", "tomato": "FF6347", "turquoise": "40E0D0", "violet": "EE82EE", "wheat": "F5DEB3", "white": "FFFFFF", "whitesmoke": "F5F5F5", "yellow": "FFFF00", "yellowgreen": "9ACD32" }; WebInspector.Color.AdvancedNickNames = { "transparent": [[0, 0, 0, 0], [0, 0, 0, 0], "transparent"], "rgba(0,0,0,0)": [[0, 0, 0, 0], [0, 0, 0, 0], "transparent"], "hsla(0,0,0,0)": [[0, 0, 0, 0], [0, 0, 0, 0], "transparent"], }; WebInspector.Color.PageHighlight = { Content: WebInspector.Color.fromRGBA(111, 168, 220, .66), ContentLight: WebInspector.Color.fromRGBA(111, 168, 220, .5), ContentOutline: WebInspector.Color.fromRGBA(9, 83, 148), Padding: WebInspector.Color.fromRGBA(147, 196, 125, .55), PaddingLight: WebInspector.Color.fromRGBA(147, 196, 125, .4), Border: WebInspector.Color.fromRGBA(255, 229, 153, .66), BorderLight: WebInspector.Color.fromRGBA(255, 229, 153, .5), Margin: WebInspector.Color.fromRGBA(246, 178, 107, .66), MarginLight: WebInspector.Color.fromRGBA(246, 178, 107, .5) } WebInspector.Color.Format = { Original: "original", Nickname: "nickname", HEX: "hex", ShortHEX: "shorthex", RGB: "rgb", RGBA: "rgba", HSL: "hsl", HSLA: "hsla" } WebInspector.CSSCompletions = function(properties) { this._values = []; this._longhands = {}; this._shorthands = {}; for (var i = 0; i < properties.length; ++i) { var property = properties[i]; if (typeof property === "string") { this._values.push(property); continue; } var propertyName = property.name; this._values.push(propertyName); var longhands = properties[i].longhands; if (longhands) { this._longhands[propertyName] = longhands; for (var j = 0; j < longhands.length; ++j) { var longhandName = longhands[j]; var shorthands = this._shorthands[longhandName]; if (!shorthands) { shorthands = []; this._shorthands[longhandName] = shorthands; } shorthands.push(propertyName); } } } this._values.sort(); } WebInspector.CSSCompletions.cssPropertiesMetainfo = null; WebInspector.CSSCompletions.requestCSSNameCompletions = function() { function propertyNamesCallback(error, properties) { if (!error) WebInspector.CSSCompletions.cssPropertiesMetainfo = new WebInspector.CSSCompletions(properties); } CSSAgent.getSupportedCSSProperties(propertyNamesCallback); } WebInspector.CSSCompletions.cssPropertiesMetainfoKeySet = function() { if (!WebInspector.CSSCompletions._cssPropertiesMetainfoKeySet) WebInspector.CSSCompletions._cssPropertiesMetainfoKeySet = WebInspector.CSSCompletions.cssPropertiesMetainfo.keySet(); return WebInspector.CSSCompletions._cssPropertiesMetainfoKeySet; } WebInspector.CSSCompletions.Weight = { "-webkit-animation": 1, "-webkit-animation-duration": 1, "-webkit-animation-iteration-count": 1, "-webkit-animation-name": 1, "-webkit-animation-timing-function": 1, "-webkit-appearance": 1, "-webkit-background-clip": 2, "-webkit-border-horizontal-spacing": 1, "-webkit-border-vertical-spacing": 1, "-webkit-box-shadow": 24, "-webkit-font-smoothing": 2, "-webkit-transform": 1, "-webkit-transition": 8, "-webkit-transition-delay": 7, "-webkit-transition-duration": 7, "-webkit-transition-property": 7, "-webkit-transition-timing-function": 6, "-webkit-user-select": 1, "background": 222, "background-attachment": 144, "background-clip": 143, "background-color": 222, "background-image": 201, "background-origin": 142, "background-size": 25, "border": 121, "border-bottom": 121, "border-bottom-color": 121, "border-bottom-left-radius": 50, "border-bottom-right-radius": 50, "border-bottom-style": 114, "border-bottom-width": 120, "border-collapse": 3, "border-left": 95, "border-left-color": 95, "border-left-style": 89, "border-left-width": 94, "border-radius": 50, "border-right": 93, "border-right-color": 93, "border-right-style": 88, "border-right-width": 93, "border-top": 111, "border-top-color": 111, "border-top-left-radius": 49, "border-top-right-radius": 49, "border-top-style": 104, "border-top-width": 109, "bottom": 16, "box-shadow": 25, "box-sizing": 2, "clear": 23, "color": 237, "cursor": 34, "direction": 4, "display": 210, "fill": 2, "filter": 1, "float": 105, "font": 174, "font-family": 25, "font-size": 174, "font-style": 9, "font-weight": 89, "height": 161, "left": 54, "letter-spacing": 3, "line-height": 75, "list-style": 17, "list-style-image": 8, "list-style-position": 8, "list-style-type": 17, "margin": 241, "margin-bottom": 226, "margin-left": 225, "margin-right": 213, "margin-top": 241, "max-height": 5, "max-width": 11, "min-height": 9, "min-width": 6, "opacity": 24, "outline": 10, "outline-color": 10, "outline-style": 10, "outline-width": 10, "overflow": 57, "overflow-x": 56, "overflow-y": 57, "padding": 216, "padding-bottom": 208, "padding-left": 216, "padding-right": 206, "padding-top": 216, "position": 136, "resize": 1, "right": 29, "stroke": 1, "stroke-width": 1, "table-layout": 1, "text-align": 66, "text-decoration": 53, "text-indent": 9, "text-overflow": 8, "text-shadow": 19, "text-transform": 5, "top": 71, "unicode-bidi": 1, "vertical-align": 37, "visibility": 11, "white-space": 24, "width": 255, "word-wrap": 6, "z-index": 32, "zoom": 10 }; WebInspector.CSSCompletions.prototype = { startsWith: function(prefix) { var firstIndex = this._firstIndexOfPrefix(prefix); if (firstIndex === -1) return []; var results = []; while (firstIndex < this._values.length && this._values[firstIndex].startsWith(prefix)) results.push(this._values[firstIndex++]); return results; }, mostUsedOf: function(properties) { var maxWeight = 0; var index = 0; for (var i = 0; i < properties.length; i++) { var weight = WebInspector.CSSCompletions.Weight[properties[i]]; if (weight > maxWeight) { maxWeight = weight; index = i; } } return index; }, _firstIndexOfPrefix: function(prefix) { if (!this._values.length) return -1; if (!prefix) return 0; var maxIndex = this._values.length - 1; var minIndex = 0; var foundIndex; do { var middleIndex = (maxIndex + minIndex) >> 1; if (this._values[middleIndex].startsWith(prefix)) { foundIndex = middleIndex; break; } if (this._values[middleIndex] < prefix) minIndex = middleIndex + 1; else maxIndex = middleIndex - 1; } while (minIndex <= maxIndex); if (foundIndex === undefined) return -1; while (foundIndex && this._values[foundIndex - 1].startsWith(prefix)) foundIndex--; return foundIndex; }, keySet: function() { if (!this._keySet) this._keySet = this._values.keySet(); return this._keySet; }, next: function(str, prefix) { return this._closest(str, prefix, 1); }, previous: function(str, prefix) { return this._closest(str, prefix, -1); }, _closest: function(str, prefix, shift) { if (!str) return ""; var index = this._values.indexOf(str); if (index === -1) return ""; if (!prefix) { index = (index + this._values.length + shift) % this._values.length; return this._values[index]; } var propertiesWithPrefix = this.startsWith(prefix); var j = propertiesWithPrefix.indexOf(str); j = (j + propertiesWithPrefix.length + shift) % propertiesWithPrefix.length; return propertiesWithPrefix[j]; }, longhands: function(shorthand) { return this._longhands[shorthand]; }, shorthands: function(longhand) { return this._shorthands[longhand]; } } WebInspector.CSSKeywordCompletions = {} WebInspector.CSSKeywordCompletions.forProperty = function(propertyName) { var acceptedKeywords = ["initial"]; if (propertyName in WebInspector.CSSKeywordCompletions._propertyKeywordMap) acceptedKeywords = acceptedKeywords.concat(WebInspector.CSSKeywordCompletions._propertyKeywordMap[propertyName]); if (propertyName in WebInspector.CSSKeywordCompletions._colorAwareProperties) acceptedKeywords = acceptedKeywords.concat(WebInspector.CSSKeywordCompletions._colors); if (propertyName in WebInspector.CSSKeywordCompletions.InheritedProperties) acceptedKeywords.push("inherit"); return new WebInspector.CSSCompletions(acceptedKeywords); } WebInspector.CSSKeywordCompletions.isColorAwareProperty = function(propertyName) { return WebInspector.CSSKeywordCompletions._colorAwareProperties[propertyName] === true; } WebInspector.CSSKeywordCompletions.colors = function() { if (!WebInspector.CSSKeywordCompletions._colorsKeySet) WebInspector.CSSKeywordCompletions._colorsKeySet = WebInspector.CSSKeywordCompletions._colors.keySet(); return WebInspector.CSSKeywordCompletions._colorsKeySet; } WebInspector.CSSKeywordCompletions.InheritedProperties = [ "azimuth", "border-collapse", "border-spacing", "caption-side", "color", "cursor", "direction", "elevation", "empty-cells", "font-family", "font-size", "font-style", "font-variant", "font-weight", "font", "letter-spacing", "line-height", "list-style-image", "list-style-position", "list-style-type", "list-style", "orphans", "pitch-range", "pitch", "quotes", "richness", "speak-header", "speak-numeral", "speak-punctuation", "speak", "speech-rate", "stress", "text-align", "text-indent", "text-transform", "text-shadow", "visibility", "voice-family", "volume", "white-space", "widows", "word-spacing" ].keySet(); WebInspector.CSSKeywordCompletions._colors = [ "aqua", "black", "blue", "fuchsia", "gray", "green", "lime", "maroon", "navy", "olive", "orange", "purple", "red", "silver", "teal", "white", "yellow", "transparent", "currentcolor", "grey", "aliceblue", "antiquewhite", "aquamarine", "azure", "beige", "bisque", "blanchedalmond", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "gainsboro", "ghostwhite", "gold", "goldenrod", "greenyellow", "honeydew", "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "limegreen", "linen", "magenta", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "oldlace", "olivedrab", "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "thistle", "tomato", "turquoise", "violet", "wheat", "whitesmoke", "yellowgreen" ]; WebInspector.CSSKeywordCompletions._colorAwareProperties = [ "background", "background-color", "background-image", "border", "border-color", "border-top", "border-right", "border-bottom", "border-left", "border-top-color", "border-right-color", "border-bottom-color", "border-left-color", "box-shadow", "color", "fill", "outline", "outline-color", "stroke", "text-line-through", "text-line-through-color", "text-overline", "text-overline-color", "text-shadow", "text-underline", "text-underline-color", "-webkit-box-shadow", "-webkit-text-emphasis", "-webkit-text-emphasis-color" ].keySet(); WebInspector.CSSKeywordCompletions._propertyKeywordMap = { "table-layout": [ "auto", "fixed" ], "visibility": [ "hidden", "visible", "collapse" ], "background-repeat": [ "repeat", "repeat-x", "repeat-y", "no-repeat", "space", "round" ], "text-underline": [ "none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave" ], "content": [ "list-item", "close-quote", "no-close-quote", "no-open-quote", "open-quote" ], "list-style-image": [ "none" ], "clear": [ "none", "left", "right", "both" ], "text-underline-mode": [ "continuous", "skip-white-space" ], "overflow-x": [ "hidden", "auto", "visible", "overlay", "scroll" ], "stroke-linejoin": [ "round", "miter", "bevel" ], "baseline-shift": [ "baseline", "sub", "super" ], "border-bottom-width": [ "medium", "thick", "thin" ], "marquee-speed": [ "normal", "slow", "fast" ], "margin-top-collapse": [ "collapse", "separate", "discard" ], "max-height": [ "none" ], "box-orient": [ "horizontal", "vertical", "inline-axis", "block-axis" ], "font-stretch": [ "normal", "wider", "narrower", "ultra-condensed", "extra-condensed", "condensed", "semi-condensed", "semi-expanded", "expanded", "extra-expanded", "ultra-expanded" ], "-webkit-color-correction": [ "default", "srgb" ], "text-underline-style": [ "none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave" ], "text-overline-mode": [ "continuous", "skip-white-space" ], "-webkit-background-composite": [ "highlight", "clear", "copy", "source-over", "source-in", "source-out", "source-atop", "destination-over", "destination-in", "destination-out", "destination-atop", "xor", "plus-darker", "plus-lighter" ], "border-left-width": [ "medium", "thick", "thin" ], "-webkit-writing-mode": [ "lr", "rl", "tb", "lr-tb", "rl-tb", "tb-rl", "horizontal-tb", "vertical-rl", "vertical-lr", "horizontal-bt" ], "text-line-through-mode": [ "continuous", "skip-white-space" ], "border-collapse": [ "collapse", "separate" ], "page-break-inside": [ "auto", "avoid" ], "border-top-width": [ "medium", "thick", "thin" ], "outline-color": [ "invert" ], "text-line-through-style": [ "none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave" ], "outline-style": [ "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double" ], "cursor": [ "none", "copy", "auto", "crosshair", "default", "pointer", "move", "vertical-text", "cell", "context-menu", "alias", "progress", "no-drop", "not-allowed", "-webkit-zoom-in", "-webkit-zoom-out", "e-resize", "ne-resize", "nw-resize", "n-resize", "se-resize", "sw-resize", "s-resize", "w-resize", "ew-resize", "ns-resize", "nesw-resize", "nwse-resize", "col-resize", "row-resize", "text", "wait", "help", "all-scroll", "-webkit-grab", "-webkit-grabbing" ], "border-width": [ "medium", "thick", "thin" ], "size": [ "a3", "a4", "a5", "b4", "b5", "landscape", "ledger", "legal", "letter", "portrait" ], "background-size": [ "contain", "cover" ], "direction": [ "ltr", "rtl" ], "marquee-direction": [ "left", "right", "auto", "reverse", "forwards", "backwards", "ahead", "up", "down" ], "enable-background": [ "accumulate", "new" ], "float": [ "none", "left", "right" ], "overflow-y": [ "hidden", "auto", "visible", "overlay", "scroll" ], "margin-bottom-collapse": [ "collapse", "separate", "discard" ], "box-reflect": [ "left", "right", "above", "below" ], "overflow": [ "hidden", "auto", "visible", "overlay", "scroll" ], "text-rendering": [ "auto", "optimizeSpeed", "optimizeLegibility", "geometricPrecision" ], "text-align": [ "-webkit-auto", "left", "right", "center", "justify", "-webkit-left", "-webkit-right", "-webkit-center" ], "list-style-position": [ "outside", "inside" ], "margin-bottom": [ "auto" ], "color-interpolation": [ "linearrgb" ], "background-origin": [ "border-box", "content-box", "padding-box" ], "word-wrap": [ "normal", "break-word" ], "font-weight": [ "normal", "bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900" ], "margin-before-collapse": [ "collapse", "separate", "discard" ], "text-overline-width": [ "normal", "medium", "auto", "thick", "thin" ], "text-transform": [ "none", "capitalize", "uppercase", "lowercase" ], "border-right-style": [ "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double" ], "border-left-style": [ "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double" ], "-webkit-text-emphasis": [ "circle", "filled", "open", "dot", "double-circle", "triangle", "sesame" ], "font-style": [ "italic", "oblique", "normal" ], "speak": [ "none", "normal", "spell-out", "digits", "literal-punctuation", "no-punctuation" ], "text-line-through": [ "none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave", "continuous", "skip-white-space" ], "color-rendering": [ "auto", "optimizeSpeed", "optimizeQuality" ], "list-style-type": [ "none", "disc", "circle", "square", "decimal", "decimal-leading-zero", "arabic-indic", "binary", "bengali", "cambodian", "khmer", "devanagari", "gujarati", "gurmukhi", "kannada", "lower-hexadecimal", "lao", "malayalam", "mongolian", "myanmar", "octal", "oriya", "persian", "urdu", "telugu", "tibetan", "thai", "upper-hexadecimal", "lower-roman", "upper-roman", "lower-greek", "lower-alpha", "lower-latin", "upper-alpha", "upper-latin", "afar", "ethiopic-halehame-aa-et", "ethiopic-halehame-aa-er", "amharic", "ethiopic-halehame-am-et", "amharic-abegede", "ethiopic-abegede-am-et", "cjk-earthly-branch", "cjk-heavenly-stem", "ethiopic", "ethiopic-halehame-gez", "ethiopic-abegede", "ethiopic-abegede-gez", "hangul-consonant", "hangul", "lower-norwegian", "oromo", "ethiopic-halehame-om-et", "sidama", "ethiopic-halehame-sid-et", "somali", "ethiopic-halehame-so-et", "tigre", "ethiopic-halehame-tig", "tigrinya-er", "ethiopic-halehame-ti-er", "tigrinya-er-abegede", "ethiopic-abegede-ti-er", "tigrinya-et", "ethiopic-halehame-ti-et", "tigrinya-et-abegede", "ethiopic-abegede-ti-et", "upper-greek", "upper-norwegian", "asterisks", "footnotes", "hebrew", "armenian", "lower-armenian", "upper-armenian", "georgian", "cjk-ideographic", "hiragana", "katakana", "hiragana-iroha", "katakana-iroha" ], "-webkit-text-combine": [ "none", "horizontal" ], "outline": [ "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double" ], "font": [ "caption", "icon", "menu", "message-box", "small-caption", "-webkit-mini-control", "-webkit-small-control", "-webkit-control", "status-bar", "italic", "oblique", "small-caps", "normal", "bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900", "xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large", "-webkit-xxx-large", "smaller", "larger", "serif", "sans-serif", "cursive", "fantasy", "monospace", "-webkit-body", "-webkit-pictograph" ], "dominant-baseline": [ "middle", "auto", "central", "text-before-edge", "text-after-edge", "ideographic", "alphabetic", "hanging", "mathematical", "use-script", "no-change", "reset-size" ], "display": [ "none", "inline", "block", "list-item", "run-in", "compact", "inline-block", "table", "inline-table", "table-row-group", "table-header-group", "table-footer-group", "table-row", "table-column-group", "table-column", "table-cell", "table-caption", "-webkit-box", "-webkit-inline-box", "-wap-marquee" ], "-webkit-text-emphasis-position": [ "over", "under" ], "image-rendering": [ "auto", "optimizeSpeed", "optimizeQuality" ], "alignment-baseline": [ "baseline", "middle", "auto", "before-edge", "after-edge", "central", "text-before-edge", "text-after-edge", "ideographic", "alphabetic", "hanging", "mathematical" ], "outline-width": [ "medium", "thick", "thin" ], "text-line-through-width": [ "normal", "medium", "auto", "thick", "thin" ], "box-align": [ "baseline", "center", "stretch", "start", "end" ], "border-right-width": [ "medium", "thick", "thin" ], "border-top-style": [ "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double" ], "line-height": [ "normal" ], "text-overflow": [ "clip", "ellipsis" ], "box-direction": [ "normal", "reverse" ], "margin-after-collapse": [ "collapse", "separate", "discard" ], "page-break-before": [ "left", "right", "auto", "always", "avoid" ], "-webkit-hyphens": [ "none", "auto", "manual" ], "border-image": [ "repeat", "stretch" ], "text-decoration": [ "blink", "line-through", "overline", "underline" ], "position": [ "absolute", "fixed", "relative", "static" ], "font-family": [ "serif", "sans-serif", "cursive", "fantasy", "monospace", "-webkit-body", "-webkit-pictograph" ], "text-overflow-mode": [ "clip", "ellipsis" ], "border-bottom-style": [ "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double" ], "unicode-bidi": [ "normal", "bidi-override", "embed" ], "clip-rule": [ "nonzero", "evenodd" ], "margin-left": [ "auto" ], "margin-top": [ "auto" ], "zoom": [ "document", "reset" ], "text-overline-style": [ "none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave" ], "max-width": [ "none" ], "empty-cells": [ "hide", "show" ], "pointer-events": [ "none", "all", "auto", "visible", "visiblepainted", "visiblefill", "visiblestroke", "painted", "fill", "stroke" ], "letter-spacing": [ "normal" ], "background-clip": [ "border-box", "content-box", "padding-box" ], "-webkit-font-smoothing": [ "none", "auto", "antialiased", "subpixel-antialiased" ], "border": [ "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double" ], "font-size": [ "xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large", "-webkit-xxx-large", "smaller", "larger" ], "font-variant": [ "small-caps", "normal" ], "vertical-align": [ "baseline", "middle", "sub", "super", "text-top", "text-bottom", "top", "bottom", "-webkit-baseline-middle" ], "marquee-style": [ "none", "scroll", "slide", "alternate" ], "white-space": [ "normal", "nowrap", "pre", "pre-line", "pre-wrap" ], "text-underline-width": [ "normal", "medium", "auto", "thick", "thin" ], "box-lines": [ "single", "multiple" ], "page-break-after": [ "left", "right", "auto", "always", "avoid" ], "clip-path": [ "none" ], "margin": [ "auto" ], "marquee-repetition": [ "infinite" ], "margin-right": [ "auto" ], "-webkit-text-emphasis-style": [ "circle", "filled", "open", "dot", "double-circle", "triangle", "sesame" ], "-webkit-transform": [ "scale", "scaleX", "scaleY", "scale3d", "rotate", "rotateX", "rotateY", "rotateZ", "rotate3d", "skew", "skewX", "skewY", "translate", "translateX", "translateY", "translateZ", "translate3d", "matrix", "matrix3d", "perspective" ] } WebInspector.PanelEnablerView = function(identifier, headingText, disclaimerText, buttonTitle) { WebInspector.View.call(this); this.registerRequiredCSS("panelEnablerView.css"); this.element.addStyleClass("panel-enabler-view"); this.element.addStyleClass(identifier); this.contentElement = document.createElement("div"); this.contentElement.className = "panel-enabler-view-content"; this.element.appendChild(this.contentElement); this.imageElement = document.createElement("img"); this.contentElement.appendChild(this.imageElement); this.choicesForm = document.createElement("form"); this.contentElement.appendChild(this.choicesForm); this.headerElement = document.createElement("h1"); this.headerElement.textContent = headingText; this.choicesForm.appendChild(this.headerElement); var self = this; function enableOption(text, checked) { var label = document.createElement("label"); var option = document.createElement("input"); option.type = "radio"; option.name = "enable-option"; if (checked) option.checked = true; label.appendChild(option); label.appendChild(document.createTextNode(text)); self.choicesForm.appendChild(label); return option; }; this.enabledForSession = enableOption(WebInspector.UIString("Only enable for this session"), true); this.enabledAlways = enableOption(WebInspector.UIString("Always enable"), false); this.disclaimerElement = document.createElement("div"); this.disclaimerElement.className = "panel-enabler-disclaimer"; this.disclaimerElement.textContent = disclaimerText; this.choicesForm.appendChild(this.disclaimerElement); this.enableButton = document.createElement("button"); this.enableButton.setAttribute("type", "button"); this.enableButton.textContent = buttonTitle; this.enableButton.addEventListener("click", this._enableButtonCicked.bind(this), false); this.choicesForm.appendChild(this.enableButton); } WebInspector.PanelEnablerView.prototype = { _enableButtonCicked: function() { this.dispatchEventToListeners("enable clicked"); }, onResize: function() { this.imageElement.removeStyleClass("hidden"); if (this.element.offsetWidth < (this.choicesForm.offsetWidth + this.imageElement.offsetWidth)) this.imageElement.addStyleClass("hidden"); }, get alwaysEnabled() { return this.enabledAlways.checked; }, __proto__: WebInspector.View.prototype } WebInspector.StatusBarButton = function(title, className, states) { this.element = document.createElement("button"); this.element.className = className + " status-bar-item"; this.element.addEventListener("click", this._clicked.bind(this), false); this.glyph = document.createElement("div"); this.glyph.className = "glyph"; this.element.appendChild(this.glyph); this.glyphShadow = document.createElement("div"); this.glyphShadow.className = "glyph shadow"; this.element.appendChild(this.glyphShadow); this.states = states; if (!states) this.states = 2; if (states == 2) this._state = false; else this._state = 0; this.title = title; this.className = className; this.disabled = false; this._visible = true; } WebInspector.StatusBarButton.width = 31; WebInspector.StatusBarButton.prototype = { _clicked: function() { this.dispatchEventToListeners("click"); if (this._showOptionsTimer) clearTimeout(this._showOptionsTimer); }, get disabled() { return this._disabled; }, set disabled(x) { if (this._disabled === x) return; this._disabled = x; this.element.disabled = x; }, get title() { return this._title; }, set title(x) { if (this._title === x) return; this._title = x; this.element.title = x; }, get state() { return this._state; }, set state(x) { if (this._state === x) return; if (this.states === 2) { if (x) this.element.addStyleClass("toggled-on"); else this.element.removeStyleClass("toggled-on"); } else { if (x !== 0) { this.element.removeStyleClass("toggled-" + this._state); this.element.addStyleClass("toggled-" + x); } else this.element.removeStyleClass("toggled-" + this._state); } this._state = x; }, get toggled() { if (this.states !== 2) throw("Only used toggled when there are 2 states, otherwise, use state"); return this.state; }, set toggled(x) { if (this.states !== 2) throw("Only used toggled when there are 2 states, otherwise, use state"); this.state = x; }, get visible() { return this._visible; }, set visible(x) { if (this._visible === x) return; if (x) this.element.removeStyleClass("hidden"); else this.element.addStyleClass("hidden"); this._visible = x; }, makeLongClickEnabled: function(buttonsProvider) { this.longClickGlyph = document.createElement("div"); this.longClickGlyph.className = "fill long-click-glyph"; this.element.appendChild(this.longClickGlyph); this.longClickGlyphShadow = document.createElement("div"); this.longClickGlyphShadow.className = "fill long-click-glyph shadow"; this.element.appendChild(this.longClickGlyphShadow); this.element.addEventListener("mousedown", mouseDown.bind(this), false); this.element.addEventListener("mouseout", mouseUp.bind(this), false); this.element.addEventListener("mouseup", mouseUp.bind(this), false); function mouseDown(e) { if (e.which !== 1) return; this._showOptionsTimer = setTimeout(this._showOptions.bind(this, buttonsProvider), 200); } function mouseUp(e) { if (e.which !== 1) return; if (this._showOptionsTimer) clearTimeout(this._showOptionsTimer); } }, _showOptions: function(buttonsProvider) { var buttons = buttonsProvider(); var mainButtonClone = new WebInspector.StatusBarButton(this.title, this.className, this.states); mainButtonClone.addEventListener("click", this._clicked, this); mainButtonClone.state = this.state; buttons.push(mainButtonClone); var mouseUpListener = mouseUp.bind(this); document.documentElement.addEventListener("mouseup", mouseUpListener, false); var optionsGlassPane = new WebInspector.GlassPane(); var optionsBarElement = optionsGlassPane.element.createChild("div", "alternate-status-bar-buttons-bar"); const buttonHeight = 24; optionsBarElement.style.height = (buttonHeight * buttons.length) + "px"; optionsBarElement.style.left = (this.element.offsetLeft + 1) + "px"; var boundMouseOver = mouseOver.bind(this); var boundMouseOut = mouseOut.bind(this); for (var i = 0; i < buttons.length; ++i) { buttons[i].element.addEventListener("mousemove", boundMouseOver, false); buttons[i].element.addEventListener("mouseout", boundMouseOut, false); optionsBarElement.appendChild(buttons[i].element); } buttons[buttons.length - 1].element.addStyleClass("emulate-active"); function mouseOver(e) { if (e.which !== 1) return; var buttonElement = e.target.enclosingNodeOrSelfWithClass("status-bar-item"); buttonElement.addStyleClass("emulate-active"); } function mouseOut(e) { if (e.which !== 1) return; var buttonElement = e.target.enclosingNodeOrSelfWithClass("status-bar-item"); buttonElement.removeStyleClass("emulate-active"); } function mouseUp(e) { if (e.which !== 1) return; optionsGlassPane.dispose(); document.documentElement.removeEventListener("mouseup", mouseUpListener, false); for (var i = 0; i < buttons.length; ++i) { if (buttons[i].element.hasStyleClass("emulate-active")) buttons[i]._clicked(); } } }, __proto__: WebInspector.Object.prototype } WebInspector.StatusBarComboBox = function(changeHandler, className) { this.element = document.createElement("span"); this.element.className = "status-bar-select-container"; this._selectElement = this.element.createChild("select", "status-bar-item"); if (changeHandler) this._selectElement.addEventListener("change", changeHandler, false); if (className) this._selectElement.addStyleClass(className); } WebInspector.StatusBarComboBox.prototype = { addOption: function(option) { this._selectElement.appendChild(option); }, removeOption: function(option) { this._selectElement.removeChild(option); }, removeOptions: function() { this._selectElement.removeChildren(); }, selectedOption: function() { if (this._selectElement.selectedIndex >= 0) return this._selectElement[this._selectElement.selectedIndex]; return null; }, select: function(option) { this._selectElement.selectedIndex = Array.prototype.indexOf.call(this._selectElement, option); } } WebInspector.TextEditor = function() { }; WebInspector.TextEditor.Events = { GutterClick: "gutterClick" }; WebInspector.TextEditor.prototype = { set mimeType(mimeType) { }, setReadOnly: function(readOnly) { }, readOnly: function() { }, defaultFocusedElement: function() { }, revealLine: function(lineNumber) { }, addBreakpoint: function(lineNumber, disabled, conditional) { }, removeBreakpoint: function(lineNumber) { }, setExecutionLine: function(lineNumber) { }, clearExecutionLine: function() { }, addDecoration: function(lineNumber, element) { }, removeDecoration: function(lineNumber, element) { }, markAndRevealRange: function(range) { }, highlightLine: function(lineNumber) { }, clearLineHighlight: function() { }, elementsToRestoreScrollPositionsFor: function() { }, inheritScrollPositions: function(textEditor) { }, beginUpdates: function() { }, endUpdates: function() { }, onResize: function() { }, editRange: function(range, text) { }, scrollToLine: function(lineNumber) { }, selection: function(textRange) { }, lastSelection: function() { }, setSelection: function(textRange) { }, setText: function(text) { }, text: function() { }, range: function() { }, line: function(lineNumber) { }, get linesCount() { }, setAttribute: function(line, name, value) { }, getAttribute: function(line, name) { }, removeAttribute: function(line, name) { }, wasShown: function() { }, willHide: function() { } } WebInspector.TextEditorDelegate = function() { } WebInspector.TextEditorDelegate.prototype = { onTextChanged: function(oldRange, newRange) { }, selectionChanged: function(textRange) { }, scrollChanged: function(lineNumber) { }, populateLineGutterContextMenu: function(contextMenu, lineNumber) { }, populateTextAreaContextMenu: function(contextMenu, lineNumber) { }, createLink: function(hrefValue, isExternal) { } } WebInspector.DefaultTextEditor = function(url, delegate) { WebInspector.View.call(this); this._delegate = delegate; this._url = url; this.registerRequiredCSS("textEditor.css"); this.element.className = "text-editor monospace"; this.element.addEventListener("mouseup", preventDefaultOnMouseUp.bind(this), false); function preventDefaultOnMouseUp(event) { if (event.button === 1) event.consume(true); } this._textModel = new WebInspector.TextEditorModel(); this._textModel.addEventListener(WebInspector.TextEditorModel.Events.TextChanged, this._textChanged, this); this._textModel.resetUndoStack(); var enterTextChangeMode = this._enterInternalTextChangeMode.bind(this); var exitTextChangeMode = this._exitInternalTextChangeMode.bind(this); var syncScrollListener = this._syncScroll.bind(this); var syncDecorationsForLineListener = this._syncDecorationsForLine.bind(this); var syncLineHeightListener = this._syncLineHeight.bind(this); this._mainPanel = new WebInspector.TextEditorMainPanel(this._delegate, this._textModel, url, syncScrollListener, syncDecorationsForLineListener, enterTextChangeMode, exitTextChangeMode); this._gutterPanel = new WebInspector.TextEditorGutterPanel(this._textModel, syncDecorationsForLineListener, syncLineHeightListener); this._mainPanel.element.addEventListener("scroll", this._handleScrollChanged.bind(this), false); this._mainPanel._container.addEventListener("focus", this._handleFocused.bind(this), false); this._gutterPanel.element.addEventListener("mousedown", this._onMouseDown.bind(this), true); this._mainPanel.element.addEventListener("mouseup", consumeMouseUp.bind(this), false); function consumeMouseUp(event) { if (event.button === 1) event.consume(false); } this.element.appendChild(this._mainPanel.element); this.element.appendChild(this._gutterPanel.element); function forwardWheelEvent(event) { var clone = document.createEvent("WheelEvent"); clone.initWebKitWheelEvent(event.wheelDeltaX, event.wheelDeltaY, event.view, event.screenX, event.screenY, event.clientX, event.clientY, event.ctrlKey, event.altKey, event.shiftKey, event.metaKey); this._mainPanel.element.dispatchEvent(clone); } this._gutterPanel.element.addEventListener("mousewheel", forwardWheelEvent.bind(this), false); this.element.addEventListener("keydown", this._handleKeyDown.bind(this), false); this.element.addEventListener("contextmenu", this._contextMenu.bind(this), true); this._registerShortcuts(); } WebInspector.DefaultTextEditor.prototype = { set mimeType(mimeType) { this._mainPanel.mimeType = mimeType; }, setReadOnly: function(readOnly) { if (this._mainPanel.readOnly() === readOnly) return; this._mainPanel.setReadOnly(readOnly, this.isShowing()); WebInspector.markBeingEdited(this.element, !readOnly); }, readOnly: function() { return this._mainPanel.readOnly(); }, get textModel() { return this._textModel; }, defaultFocusedElement: function() { return this._mainPanel.defaultFocusedElement(); }, revealLine: function(lineNumber) { this._mainPanel.revealLine(lineNumber); }, _onMouseDown: function(event) { var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number"); if (!target) return; this.dispatchEventToListeners(WebInspector.TextEditor.Events.GutterClick, { lineNumber: target.lineNumber, event: event }); }, addBreakpoint: function(lineNumber, disabled, conditional) { this.beginUpdates(); this._gutterPanel.addDecoration(lineNumber, "webkit-breakpoint"); if (disabled) this._gutterPanel.addDecoration(lineNumber, "webkit-breakpoint-disabled"); else this._gutterPanel.removeDecoration(lineNumber, "webkit-breakpoint-disabled"); if (conditional) this._gutterPanel.addDecoration(lineNumber, "webkit-breakpoint-conditional"); else this._gutterPanel.removeDecoration(lineNumber, "webkit-breakpoint-conditional"); this.endUpdates(); }, removeBreakpoint: function(lineNumber) { this.beginUpdates(); this._gutterPanel.removeDecoration(lineNumber, "webkit-breakpoint"); this._gutterPanel.removeDecoration(lineNumber, "webkit-breakpoint-disabled"); this._gutterPanel.removeDecoration(lineNumber, "webkit-breakpoint-conditional"); this.endUpdates(); }, setExecutionLine: function(lineNumber) { this._executionLineNumber = lineNumber; this._mainPanel.addDecoration(lineNumber, "webkit-execution-line"); this._gutterPanel.addDecoration(lineNumber, "webkit-execution-line"); }, clearExecutionLine: function() { if (typeof this._executionLineNumber === "number") { this._mainPanel.removeDecoration(this._executionLineNumber, "webkit-execution-line"); this._gutterPanel.removeDecoration(this._executionLineNumber, "webkit-execution-line"); } delete this._executionLineNumber; }, addDecoration: function(lineNumber, element) { this._mainPanel.addDecoration(lineNumber, element); this._gutterPanel.addDecoration(lineNumber, element); this._syncDecorationsForLine(lineNumber); }, removeDecoration: function(lineNumber, element) { this._mainPanel.removeDecoration(lineNumber, element); this._gutterPanel.removeDecoration(lineNumber, element); this._syncDecorationsForLine(lineNumber); }, markAndRevealRange: function(range) { if (range) this.setSelection(range); this._mainPanel.markAndRevealRange(range); }, highlightLine: function(lineNumber) { if (typeof lineNumber !== "number" || lineNumber < 0) return; lineNumber = Math.min(lineNumber, this._textModel.linesCount - 1); this._mainPanel.highlightLine(lineNumber); }, clearLineHighlight: function() { this._mainPanel.clearLineHighlight(); }, _freeCachedElements: function() { this._mainPanel._freeCachedElements(); this._gutterPanel._freeCachedElements(); }, elementsToRestoreScrollPositionsFor: function() { return [this._mainPanel.element]; }, inheritScrollPositions: function(textEditor) { this._mainPanel.element._scrollTop = textEditor._mainPanel.element.scrollTop; this._mainPanel.element._scrollLeft = textEditor._mainPanel.element.scrollLeft; }, beginUpdates: function() { this._mainPanel.beginUpdates(); this._gutterPanel.beginUpdates(); }, endUpdates: function() { this._mainPanel.endUpdates(); this._gutterPanel.endUpdates(); this._updatePanelOffsets(); }, onResize: function() { this._mainPanel.resize(); this._gutterPanel.resize(); this._updatePanelOffsets(); }, _textChanged: function(event) { if (!this._internalTextChangeMode) this._textModel.resetUndoStack(); this._mainPanel.textChanged(event.data.oldRange, event.data.newRange); this._gutterPanel.textChanged(event.data.oldRange, event.data.newRange); this._updatePanelOffsets(); }, editRange: function(range, text) { this._enterInternalTextChangeMode(); this._textModel.markUndoableState(); var newRange = this._textModel.editRange(range, text); this._exitInternalTextChangeMode(range, newRange); return newRange; }, _enterInternalTextChangeMode: function() { this._internalTextChangeMode = true; }, _exitInternalTextChangeMode: function(oldRange, newRange) { this._internalTextChangeMode = false; this._delegate.onTextChanged(oldRange, newRange); }, _updatePanelOffsets: function() { var lineNumbersWidth = this._gutterPanel.element.offsetWidth; if (lineNumbersWidth) this._mainPanel.element.style.setProperty("left", (lineNumbersWidth + 2) + "px"); else this._mainPanel.element.style.removeProperty("left"); }, _syncScroll: function() { var mainElement = this._mainPanel.element; var gutterElement = this._gutterPanel.element; this._gutterPanel.syncClientHeight(mainElement.clientHeight); gutterElement.scrollTop = mainElement.scrollTop; }, _syncDecorationsForLine: function(lineNumber) { if (lineNumber >= this._textModel.linesCount) return; var mainChunk = this._mainPanel.chunkForLine(lineNumber); if (mainChunk.linesCount === 1 && mainChunk.decorated) { var gutterChunk = this._gutterPanel.makeLineAChunk(lineNumber); var height = mainChunk.height; if (height) gutterChunk.element.style.setProperty("height", height + "px"); else gutterChunk.element.style.removeProperty("height"); } else { var gutterChunk = this._gutterPanel.chunkForLine(lineNumber); if (gutterChunk.linesCount === 1) gutterChunk.element.style.removeProperty("height"); } }, _syncLineHeight: function(gutterRow) { if (this._lineHeightSynced) return; if (gutterRow && gutterRow.offsetHeight) { this.element.style.setProperty("line-height", gutterRow.offsetHeight + "px"); this._lineHeightSynced = true; } }, _registerShortcuts: function() { var keys = WebInspector.KeyboardShortcut.Keys; var modifiers = WebInspector.KeyboardShortcut.Modifiers; this._shortcuts = {}; var handleEnterKey = this._mainPanel.handleEnterKey.bind(this._mainPanel); this._shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Enter.code, WebInspector.KeyboardShortcut.Modifiers.None)] = handleEnterKey; this._shortcuts[WebInspector.KeyboardShortcut.makeKey("z", modifiers.CtrlOrMeta)] = this._mainPanel.handleUndoRedo.bind(this._mainPanel, false); this._shortcuts[WebInspector.KeyboardShortcut.SelectAll] = this._handleSelectAll.bind(this); var handleRedo = this._mainPanel.handleUndoRedo.bind(this._mainPanel, true); this._shortcuts[WebInspector.KeyboardShortcut.makeKey("z", modifiers.Shift | modifiers.CtrlOrMeta)] = handleRedo; if (!WebInspector.isMac()) this._shortcuts[WebInspector.KeyboardShortcut.makeKey("y", modifiers.CtrlOrMeta)] = handleRedo; var handleTabKey = this._mainPanel.handleTabKeyPress.bind(this._mainPanel, false); var handleShiftTabKey = this._mainPanel.handleTabKeyPress.bind(this._mainPanel, true); this._shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Tab.code)] = handleTabKey; this._shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Tab.code, modifiers.Shift)] = handleShiftTabKey; }, _handleSelectAll: function() { this.setSelection(this._textModel.range()); return true; }, _handleKeyDown: function(e) { var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(e); var handler = this._shortcuts[shortcutKey]; if (handler && handler()) e.consume(true); }, _contextMenu: function(event) { var anchor = event.target.enclosingNodeOrSelfWithNodeName("a"); if (anchor) return; var contextMenu = new WebInspector.ContextMenu(event); var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number"); if (target) this._delegate.populateLineGutterContextMenu(contextMenu, target.lineNumber); else { target = this._mainPanel._enclosingLineRowOrSelf(event.target); this._delegate.populateTextAreaContextMenu(contextMenu, target && target.lineNumber); } contextMenu.show(); }, _handleScrollChanged: function(event) { var visibleFrom = this._mainPanel.element.scrollTop; var firstVisibleLineNumber = this._mainPanel._findFirstVisibleLineNumber(visibleFrom); this._delegate.scrollChanged(firstVisibleLineNumber); }, scrollToLine: function(lineNumber) { this._mainPanel.scrollToLine(lineNumber); }, _handleSelectionChange: function(event) { var textRange = this._mainPanel._getSelection(); if (textRange) { this._lastSelection = WebInspector.TextRange.createFromLocation(textRange.endLine, textRange.endColumn); } this._delegate.selectionChanged(textRange); }, selection: function(textRange) { return this._mainPanel._getSelection(); }, lastSelection: function() { return this._lastSelection; }, setSelection: function(textRange) { this._lastSelection = textRange; if (this.element.isAncestor(document.activeElement)) this._mainPanel._restoreSelection(textRange); }, setText: function(text) { this._textModel.setText(text); }, text: function() { return this._textModel.text(); }, range: function() { return this._textModel.range(); }, line: function(lineNumber) { return this._textModel.line(lineNumber); }, get linesCount() { return this._textModel.linesCount; }, setAttribute: function(line, name, value) { this._textModel.setAttribute(line, name, value); }, getAttribute: function(line, name) { return this._textModel.getAttribute(line, name); }, removeAttribute: function(line, name) { this._textModel.removeAttribute(line, name); }, wasShown: function() { if (!this.readOnly()) WebInspector.markBeingEdited(this.element, true); this._boundSelectionChangeListener = this._handleSelectionChange.bind(this); document.addEventListener("selectionchange", this._boundSelectionChangeListener, false); }, _handleFocused: function() { if (this._lastSelection) this.setSelection(this._lastSelection); }, willHide: function() { document.removeEventListener("selectionchange", this._boundSelectionChangeListener, false); delete this._boundSelectionChangeListener; if (!this.readOnly()) WebInspector.markBeingEdited(this.element, false); this._freeCachedElements(); }, __proto__: WebInspector.View.prototype } WebInspector.TextEditorChunkedPanel = function(textModel) { this._textModel = textModel; this._defaultChunkSize = 50; this._paintCoalescingLevel = 0; this._domUpdateCoalescingLevel = 0; } WebInspector.TextEditorChunkedPanel.prototype = { get textModel() { return this._textModel; }, scrollToLine: function(lineNumber) { if (lineNumber >= this._textModel.linesCount) return; var chunk = this.makeLineAChunk(lineNumber); this.element.scrollTop = chunk.offsetTop; }, revealLine: function(lineNumber) { if (lineNumber >= this._textModel.linesCount) return; var chunk = this.makeLineAChunk(lineNumber); chunk.element.scrollIntoViewIfNeeded(); }, addDecoration: function(lineNumber, decoration) { if (lineNumber >= this._textModel.linesCount) return; var chunk = this.makeLineAChunk(lineNumber); chunk.addDecoration(decoration); }, removeDecoration: function(lineNumber, decoration) { if (lineNumber >= this._textModel.linesCount) return; var chunk = this.chunkForLine(lineNumber); chunk.removeDecoration(decoration); }, _buildChunks: function() { this.beginDomUpdates(); this._container.removeChildren(); this._textChunks = []; for (var i = 0; i < this._textModel.linesCount; i += this._defaultChunkSize) { var chunk = this._createNewChunk(i, i + this._defaultChunkSize); this._textChunks.push(chunk); this._container.appendChild(chunk.element); } this._repaintAll(); this.endDomUpdates(); }, makeLineAChunk: function(lineNumber) { var chunkNumber = this._chunkNumberForLine(lineNumber); var oldChunk = this._textChunks[chunkNumber]; if (!oldChunk) { console.error("No chunk for line number: " + lineNumber); return; } if (oldChunk.linesCount === 1) return oldChunk; return this._splitChunkOnALine(lineNumber, chunkNumber, true); }, _splitChunkOnALine: function(lineNumber, chunkNumber, createSuffixChunk) { this.beginDomUpdates(); var oldChunk = this._textChunks[chunkNumber]; var wasExpanded = oldChunk.expanded; oldChunk.expanded = false; var insertIndex = chunkNumber + 1; if (lineNumber > oldChunk.startLine) { var prefixChunk = this._createNewChunk(oldChunk.startLine, lineNumber); prefixChunk.readOnly = oldChunk.readOnly; this._textChunks.splice(insertIndex++, 0, prefixChunk); this._container.insertBefore(prefixChunk.element, oldChunk.element); } var endLine = createSuffixChunk ? lineNumber + 1 : oldChunk.startLine + oldChunk.linesCount; var lineChunk = this._createNewChunk(lineNumber, endLine); lineChunk.readOnly = oldChunk.readOnly; this._textChunks.splice(insertIndex++, 0, lineChunk); this._container.insertBefore(lineChunk.element, oldChunk.element); if (oldChunk.startLine + oldChunk.linesCount > endLine) { var suffixChunk = this._createNewChunk(endLine, oldChunk.startLine + oldChunk.linesCount); suffixChunk.readOnly = oldChunk.readOnly; this._textChunks.splice(insertIndex, 0, suffixChunk); this._container.insertBefore(suffixChunk.element, oldChunk.element); } this._textChunks.splice(chunkNumber, 1); this._container.removeChild(oldChunk.element); if (wasExpanded) { if (prefixChunk) prefixChunk.expanded = true; lineChunk.expanded = true; if (suffixChunk) suffixChunk.expanded = true; } this.endDomUpdates(); return lineChunk; }, _scroll: function() { this._scheduleRepaintAll(); if (this._syncScrollListener) this._syncScrollListener(); }, _scheduleRepaintAll: function() { if (this._repaintAllTimer) clearTimeout(this._repaintAllTimer); this._repaintAllTimer = setTimeout(this._repaintAll.bind(this), 50); }, beginUpdates: function() { this._paintCoalescingLevel++; }, endUpdates: function() { this._paintCoalescingLevel--; if (!this._paintCoalescingLevel) this._repaintAll(); }, beginDomUpdates: function() { this._domUpdateCoalescingLevel++; }, endDomUpdates: function() { this._domUpdateCoalescingLevel--; }, _chunkNumberForLine: function(lineNumber) { function compareLineNumbers(value, chunk) { return value < chunk.startLine ? -1 : 1; } var insertBefore = insertionIndexForObjectInListSortedByFunction(lineNumber, this._textChunks, compareLineNumbers); return insertBefore - 1; }, chunkForLine: function(lineNumber) { return this._textChunks[this._chunkNumberForLine(lineNumber)]; }, _findFirstVisibleChunkNumber: function(visibleFrom) { function compareOffsetTops(value, chunk) { return value < chunk.offsetTop ? -1 : 1; } var insertBefore = insertionIndexForObjectInListSortedByFunction(visibleFrom, this._textChunks, compareOffsetTops); return insertBefore - 1; }, _findVisibleChunks: function(visibleFrom, visibleTo) { var from = this._findFirstVisibleChunkNumber(visibleFrom); for (var to = from + 1; to < this._textChunks.length; ++to) { if (this._textChunks[to].offsetTop >= visibleTo) break; } return { start: from, end: to }; }, _findFirstVisibleLineNumber: function(visibleFrom) { var chunk = this._textChunks[this._findFirstVisibleChunkNumber(visibleFrom)]; if (!chunk.expanded) return chunk.startLine; var lineNumbers = []; for (var i = 0; i < chunk.linesCount; ++i) { lineNumbers.push(chunk.startLine + i); } function compareLineRowOffsetTops(value, lineNumber) { var lineRow = chunk.getExpandedLineRow(lineNumber); return value < lineRow.offsetTop ? -1 : 1; } var insertBefore = insertionIndexForObjectInListSortedByFunction(visibleFrom, lineNumbers, compareLineRowOffsetTops); return lineNumbers[insertBefore - 1]; }, _repaintAll: function() { delete this._repaintAllTimer; if (this._paintCoalescingLevel || this._dirtyLines) return; var visibleFrom = this.element.scrollTop; var visibleTo = this.element.scrollTop + this.element.clientHeight; if (visibleTo) { var result = this._findVisibleChunks(visibleFrom, visibleTo); this._expandChunks(result.start, result.end); } }, _expandChunks: function(fromIndex, toIndex) { for (var i = 0; i < fromIndex; ++i) this._textChunks[i].expanded = false; for (var i = toIndex; i < this._textChunks.length; ++i) this._textChunks[i].expanded = false; for (var i = fromIndex; i < toIndex; ++i) this._textChunks[i].expanded = true; }, _totalHeight: function(firstElement, lastElement) { lastElement = (lastElement || firstElement).nextElementSibling; if (lastElement) return lastElement.offsetTop - firstElement.offsetTop; var offsetParent = firstElement.offsetParent; if (offsetParent && offsetParent.scrollHeight > offsetParent.clientHeight) return offsetParent.scrollHeight - firstElement.offsetTop; var total = 0; while (firstElement && firstElement !== lastElement) { total += firstElement.offsetHeight; firstElement = firstElement.nextElementSibling; } return total; }, resize: function() { this._repaintAll(); } } WebInspector.TextEditorGutterPanel = function(textModel, syncDecorationsForLineListener, syncLineHeightListener) { WebInspector.TextEditorChunkedPanel.call(this, textModel); this._syncDecorationsForLineListener = syncDecorationsForLineListener; this._syncLineHeightListener = syncLineHeightListener; this.element = document.createElement("div"); this.element.className = "text-editor-lines"; this._container = document.createElement("div"); this._container.className = "inner-container"; this.element.appendChild(this._container); this.element.addEventListener("scroll", this._scroll.bind(this), false); this._freeCachedElements(); this._buildChunks(); this._decorations = {}; } WebInspector.TextEditorGutterPanel.prototype = { _freeCachedElements: function() { this._cachedRows = []; }, _createNewChunk: function(startLine, endLine) { return new WebInspector.TextEditorGutterChunk(this, startLine, endLine); }, textChanged: function(oldRange, newRange) { this.beginDomUpdates(); var linesDiff = newRange.linesCount - oldRange.linesCount; if (linesDiff) { for (var chunkNumber = this._textChunks.length - 1; chunkNumber >= 0 ; --chunkNumber) { var chunk = this._textChunks[chunkNumber]; if (chunk.startLine + chunk.linesCount <= this._textModel.linesCount) break; chunk.expanded = false; this._container.removeChild(chunk.element); } this._textChunks.length = chunkNumber + 1; var totalLines = 0; if (this._textChunks.length) { var lastChunk = this._textChunks[this._textChunks.length - 1]; totalLines = lastChunk.startLine + lastChunk.linesCount; } for (var i = totalLines; i < this._textModel.linesCount; i += this._defaultChunkSize) { var chunk = this._createNewChunk(i, i + this._defaultChunkSize); this._textChunks.push(chunk); this._container.appendChild(chunk.element); } for (var lineNumber in this._decorations) { lineNumber = parseInt(lineNumber, 10); if (lineNumber < oldRange.startLine) continue; if (lineNumber === oldRange.startLine && oldRange.startColumn) continue; var lineDecorationsCopy = this._decorations[lineNumber].slice(); for (var i = 0; i < lineDecorationsCopy.length; ++i) { var decoration = lineDecorationsCopy[i]; this.removeDecoration(lineNumber, decoration); if (lineNumber < oldRange.endLine) continue; this.addDecoration(lineNumber + linesDiff, decoration); } } this._repaintAll(); } else { var chunkNumber = this._chunkNumberForLine(newRange.startLine); var chunk = this._textChunks[chunkNumber]; while (chunk && chunk.startLine <= newRange.endLine) { if (chunk.linesCount === 1) this._syncDecorationsForLineListener(chunk.startLine); chunk = this._textChunks[++chunkNumber]; } } this.endDomUpdates(); }, syncClientHeight: function(clientHeight) { if (this.element.offsetHeight > clientHeight) this._container.style.setProperty("padding-bottom", (this.element.offsetHeight - clientHeight) + "px"); else this._container.style.removeProperty("padding-bottom"); }, addDecoration: function(lineNumber, decoration) { WebInspector.TextEditorChunkedPanel.prototype.addDecoration.call(this, lineNumber, decoration); var decorations = this._decorations[lineNumber]; if (!decorations) { decorations = []; this._decorations[lineNumber] = decorations; } decorations.push(decoration); }, removeDecoration: function(lineNumber, decoration) { WebInspector.TextEditorChunkedPanel.prototype.removeDecoration.call(this, lineNumber, decoration); var decorations = this._decorations[lineNumber]; if (decorations) { decorations.remove(decoration); if (!decorations.length) delete this._decorations[lineNumber]; } }, __proto__: WebInspector.TextEditorChunkedPanel.prototype } WebInspector.TextEditorGutterChunk = function(textEditor, startLine, endLine) { this._textEditor = textEditor; this._textModel = textEditor._textModel; this.startLine = startLine; endLine = Math.min(this._textModel.linesCount, endLine); this.linesCount = endLine - startLine; this._expanded = false; this.element = document.createElement("div"); this.element.lineNumber = startLine; this.element.className = "webkit-line-number"; if (this.linesCount === 1) { var innerSpan = document.createElement("span"); innerSpan.className = "webkit-line-number-inner"; innerSpan.textContent = startLine + 1; var outerSpan = document.createElement("div"); outerSpan.className = "webkit-line-number-outer"; outerSpan.appendChild(innerSpan); this.element.appendChild(outerSpan); } else { var lineNumbers = []; for (var i = startLine; i < endLine; ++i) lineNumbers.push(i + 1); this.element.textContent = lineNumbers.join("\n"); } } WebInspector.TextEditorGutterChunk.prototype = { addDecoration: function(decoration) { this._textEditor.beginDomUpdates(); if (typeof decoration === "string") this.element.addStyleClass(decoration); this._textEditor.endDomUpdates(); }, removeDecoration: function(decoration) { this._textEditor.beginDomUpdates(); if (typeof decoration === "string") this.element.removeStyleClass(decoration); this._textEditor.endDomUpdates(); }, get expanded() { return this._expanded; }, set expanded(expanded) { if (this.linesCount === 1) this._textEditor._syncDecorationsForLineListener(this.startLine); if (this._expanded === expanded) return; this._expanded = expanded; if (this.linesCount === 1) return; this._textEditor.beginDomUpdates(); if (expanded) { this._expandedLineRows = []; var parentElement = this.element.parentElement; for (var i = this.startLine; i < this.startLine + this.linesCount; ++i) { var lineRow = this._createRow(i); parentElement.insertBefore(lineRow, this.element); this._expandedLineRows.push(lineRow); } parentElement.removeChild(this.element); this._textEditor._syncLineHeightListener(this._expandedLineRows[0]); } else { var elementInserted = false; for (var i = 0; i < this._expandedLineRows.length; ++i) { var lineRow = this._expandedLineRows[i]; var parentElement = lineRow.parentElement; if (parentElement) { if (!elementInserted) { elementInserted = true; parentElement.insertBefore(this.element, lineRow); } parentElement.removeChild(lineRow); } this._textEditor._cachedRows.push(lineRow); } delete this._expandedLineRows; } this._textEditor.endDomUpdates(); }, get height() { if (!this._expandedLineRows) return this._textEditor._totalHeight(this.element); return this._textEditor._totalHeight(this._expandedLineRows[0], this._expandedLineRows[this._expandedLineRows.length - 1]); }, get offsetTop() { return (this._expandedLineRows && this._expandedLineRows.length) ? this._expandedLineRows[0].offsetTop : this.element.offsetTop; }, _createRow: function(lineNumber) { var lineRow = this._textEditor._cachedRows.pop() || document.createElement("div"); lineRow.lineNumber = lineNumber; lineRow.className = "webkit-line-number"; lineRow.textContent = lineNumber + 1; return lineRow; } } WebInspector.TextEditorMainPanel = function(delegate, textModel, url, syncScrollListener, syncDecorationsForLineListener, enterTextChangeMode, exitTextChangeMode) { WebInspector.TextEditorChunkedPanel.call(this, textModel); this._delegate = delegate; this._syncScrollListener = syncScrollListener; this._syncDecorationsForLineListener = syncDecorationsForLineListener; this._enterTextChangeMode = enterTextChangeMode; this._exitTextChangeMode = exitTextChangeMode; this._url = url; this._highlighter = new WebInspector.TextEditorHighlighter(textModel, this._highlightDataReady.bind(this)); this._readOnly = true; this.element = document.createElement("div"); this.element.className = "text-editor-contents"; this.element.tabIndex = 0; this._container = document.createElement("div"); this._container.className = "inner-container"; this._container.tabIndex = 0; this.element.appendChild(this._container); this.element.addEventListener("scroll", this._scroll.bind(this), false); this.element.addEventListener("focus", this._handleElementFocus.bind(this), false); this._handleDOMUpdatesCallback = this._handleDOMUpdates.bind(this); this._container.addEventListener("DOMCharacterDataModified", this._handleDOMUpdatesCallback, false); this._container.addEventListener("DOMNodeInserted", this._handleDOMUpdatesCallback, false); this._container.addEventListener("DOMSubtreeModified", this._handleDOMUpdatesCallback, false); this._freeCachedElements(); this._buildChunks(); } WebInspector.TextEditorMainPanel.prototype = { set mimeType(mimeType) { this._highlighter.mimeType = mimeType; }, setReadOnly: function(readOnly, requestFocus) { if (this._readOnly === readOnly) return; this.beginDomUpdates(); this._readOnly = readOnly; if (this._readOnly) this._container.removeStyleClass("text-editor-editable"); else { this._container.addStyleClass("text-editor-editable"); if (requestFocus) this._updateSelectionOnStartEditing(); } this.endDomUpdates(); }, readOnly: function() { return this._readOnly; }, _handleElementFocus: function() { if (!this._readOnly) this._container.focus(); }, defaultFocusedElement: function() { if (this._readOnly) return this.element; return this._container; }, _updateSelectionOnStartEditing: function() { this._container.focus(); var selection = window.getSelection(); if (selection.rangeCount) { var commonAncestorContainer = selection.getRangeAt(0).commonAncestorContainer; if (this._container.isSelfOrAncestor(commonAncestorContainer)) return; } selection.removeAllRanges(); var range = document.createRange(); range.setStart(this._container, 0); range.setEnd(this._container, 0); selection.addRange(range); }, setEditableRange: function(startLine, endLine) { this.beginDomUpdates(); var firstChunkNumber = this._chunkNumberForLine(startLine); var firstChunk = this._textChunks[firstChunkNumber]; if (firstChunk.startLine !== startLine) { this._splitChunkOnALine(startLine, firstChunkNumber); firstChunkNumber += 1; } var lastChunkNumber = this._textChunks.length; if (endLine !== this._textModel.linesCount) { lastChunkNumber = this._chunkNumberForLine(endLine); var lastChunk = this._textChunks[lastChunkNumber]; if (lastChunk && lastChunk.startLine !== endLine) { this._splitChunkOnALine(endLine, lastChunkNumber); lastChunkNumber += 1; } } for (var chunkNumber = 0; chunkNumber < firstChunkNumber; ++chunkNumber) this._textChunks[chunkNumber].readOnly = true; for (var chunkNumber = firstChunkNumber; chunkNumber < lastChunkNumber; ++chunkNumber) this._textChunks[chunkNumber].readOnly = false; for (var chunkNumber = lastChunkNumber; chunkNumber < this._textChunks.length; ++chunkNumber) this._textChunks[chunkNumber].readOnly = true; this.endDomUpdates(); }, clearEditableRange: function() { for (var chunkNumber = 0; chunkNumber < this._textChunks.length; ++chunkNumber) this._textChunks[chunkNumber].readOnly = false; }, markAndRevealRange: function(range) { if (this._rangeToMark) { var markedLine = this._rangeToMark.startLine; delete this._rangeToMark; if (!this._dirtyLines) { this.beginDomUpdates(); var chunk = this.chunkForLine(markedLine); var wasExpanded = chunk.expanded; chunk.expanded = false; chunk.updateCollapsedLineRow(); chunk.expanded = wasExpanded; this.endDomUpdates(); } else this._paintLines(markedLine, markedLine + 1); } if (range) { this._rangeToMark = range; this.revealLine(range.startLine); var chunk = this.makeLineAChunk(range.startLine); this._paintLine(chunk.element); if (this._markedRangeElement) this._markedRangeElement.scrollIntoViewIfNeeded(); } delete this._markedRangeElement; }, highlightLine: function(lineNumber) { this.clearLineHighlight(); this._highlightedLine = lineNumber; this.revealLine(lineNumber); if (!this._readOnly) this._restoreSelection(WebInspector.TextRange.createFromLocation(lineNumber, 0), false); this.addDecoration(lineNumber, "webkit-highlighted-line"); }, clearLineHighlight: function() { if (typeof this._highlightedLine === "number") { this.removeDecoration(this._highlightedLine, "webkit-highlighted-line"); delete this._highlightedLine; } }, _freeCachedElements: function() { this._cachedSpans = []; this._cachedTextNodes = []; this._cachedRows = []; }, handleUndoRedo: function(redo) { if (this.readOnly()) return false; if (this._dirtyLines) return false; this.beginUpdates(); function before() { this._enterTextChangeMode(); } function after(oldRange, newRange) { this._exitTextChangeMode(oldRange, newRange); } var range = redo ? this._textModel.redo(before.bind(this), after.bind(this)) : this._textModel.undo(before.bind(this), after.bind(this)); this.endUpdates(); if (range) this._restoreSelection(range, true); return true; }, handleTabKeyPress: function(shiftKey) { if (this.readOnly()) return false; if (this._dirtyLines) return false; var selection = this._getSelection(); if (!selection) return false; var range = selection.normalize(); this.beginUpdates(); this._enterTextChangeMode(); var newRange; var rangeWasEmpty = range.isEmpty(); if (shiftKey) newRange = this._unindentLines(range); else { if (rangeWasEmpty) newRange = this._editRange(range, WebInspector.settings.textEditorIndent.get()); else newRange = this._indentLines(range); } this._exitTextChangeMode(range, newRange); this.endUpdates(); if (rangeWasEmpty) newRange.startColumn = newRange.endColumn; this._restoreSelection(newRange, true); return true; }, _indentLines: function(range) { var indent = WebInspector.settings.textEditorIndent.get(); if (this._lastEditedRange) this._textModel.markUndoableState(); var newRange = range.clone(); if (range.startColumn) newRange.startColumn += indent.length; var indentEndLine = range.endLine; if (range.endColumn) newRange.endColumn += indent.length; else indentEndLine--; for (var lineNumber = range.startLine; lineNumber <= indentEndLine; lineNumber++) this._textModel.editRange(WebInspector.TextRange.createFromLocation(lineNumber, 0), indent); this._lastEditedRange = newRange; return newRange; }, _unindentLines: function(range) { if (this._lastEditedRange) this._textModel.markUndoableState(); var indent = WebInspector.settings.textEditorIndent.get(); var indentLength = indent === WebInspector.TextEditorModel.Indent.TabCharacter ? 4 : indent.length; var lineIndentRegex = new RegExp("^ {1," + indentLength + "}"); var newRange = range.clone(); var indentEndLine = range.endLine; if (!range.endColumn) indentEndLine--; for (var lineNumber = range.startLine; lineNumber <= indentEndLine; lineNumber++) { var line = this._textModel.line(lineNumber); var firstCharacter = line.charAt(0); var lineIndentLength; if (firstCharacter === " ") lineIndentLength = line.match(lineIndentRegex)[0].length; else if (firstCharacter === "\t") lineIndentLength = 1; else continue; this._textModel.editRange(new WebInspector.TextRange(lineNumber, 0, lineNumber, lineIndentLength), ""); if (lineNumber === range.startLine) newRange.startColumn = Math.max(0, newRange.startColumn - lineIndentLength); if (lineNumber === range.endLine) newRange.endColumn = Math.max(0, newRange.endColumn - lineIndentLength); } this._lastEditedRange = newRange; return newRange; }, handleEnterKey: function() { if (this.readOnly()) return false; if (this._dirtyLines) return false; var range = this._getSelection(); if (!range) return false; range = range.normalize(); if (range.endColumn === 0) return false; var line = this._textModel.line(range.startLine); var linePrefix = line.substring(0, range.startColumn); var indentMatch = linePrefix.match(/^\s+/); var currentIndent = indentMatch ? indentMatch[0] : ""; var textEditorIndent = WebInspector.settings.textEditorIndent.get(); var indent = WebInspector.TextEditorModel.endsWithBracketRegex.test(linePrefix) ? currentIndent + textEditorIndent : currentIndent; if (!indent) return false; this.beginUpdates(); this._enterTextChangeMode(); var lineBreak = this._textModel.lineBreak; var newRange; if (range.isEmpty() && line.substr(range.endColumn - 1, 2) === '{}') { newRange = this._editRange(range, lineBreak + indent + lineBreak + currentIndent); newRange.endLine--; newRange.endColumn += textEditorIndent.length; } else newRange = this._editRange(range, lineBreak + indent); this._exitTextChangeMode(range, newRange); this.endUpdates(); this._restoreSelection(newRange.collapseToEnd(), true); return true; }, _splitChunkOnALine: function(lineNumber, chunkNumber, createSuffixChunk) { var selection = this._getSelection(); var chunk = WebInspector.TextEditorChunkedPanel.prototype._splitChunkOnALine.call(this, lineNumber, chunkNumber, createSuffixChunk); this._restoreSelection(selection); return chunk; }, beginDomUpdates: function() { WebInspector.TextEditorChunkedPanel.prototype.beginDomUpdates.call(this); if (this._domUpdateCoalescingLevel === 1) { this._container.removeEventListener("DOMCharacterDataModified", this._handleDOMUpdatesCallback, false); this._container.removeEventListener("DOMNodeInserted", this._handleDOMUpdatesCallback, false); this._container.removeEventListener("DOMSubtreeModified", this._handleDOMUpdatesCallback, false); } }, endDomUpdates: function() { WebInspector.TextEditorChunkedPanel.prototype.endDomUpdates.call(this); if (this._domUpdateCoalescingLevel === 0) { this._container.addEventListener("DOMCharacterDataModified", this._handleDOMUpdatesCallback, false); this._container.addEventListener("DOMNodeInserted", this._handleDOMUpdatesCallback, false); this._container.addEventListener("DOMSubtreeModified", this._handleDOMUpdatesCallback, false); } }, _buildChunks: function() { for (var i = 0; i < this._textModel.linesCount; ++i) this._textModel.removeAttribute(i, "highlight"); WebInspector.TextEditorChunkedPanel.prototype._buildChunks.call(this); }, _createNewChunk: function(startLine, endLine) { return new WebInspector.TextEditorMainChunk(this, startLine, endLine); }, _expandChunks: function(fromIndex, toIndex) { var lastChunk = this._textChunks[toIndex - 1]; var lastVisibleLine = lastChunk.startLine + lastChunk.linesCount; var selection = this._getSelection(); this._muteHighlightListener = true; this._highlighter.highlight(lastVisibleLine); delete this._muteHighlightListener; this._restorePaintLinesOperationsCredit(); WebInspector.TextEditorChunkedPanel.prototype._expandChunks.call(this, fromIndex, toIndex); this._adjustPaintLinesOperationsRefreshValue(); this._restoreSelection(selection); }, _highlightDataReady: function(fromLine, toLine) { if (this._muteHighlightListener) return; this._restorePaintLinesOperationsCredit(); this._paintLines(fromLine, toLine, true ); }, _schedulePaintLines: function(startLine, endLine) { if (startLine >= endLine) return; if (!this._scheduledPaintLines) { this._scheduledPaintLines = [ { startLine: startLine, endLine: endLine } ]; this._paintScheduledLinesTimer = setTimeout(this._paintScheduledLines.bind(this), 0); } else { for (var i = 0; i < this._scheduledPaintLines.length; ++i) { var chunk = this._scheduledPaintLines[i]; if (chunk.startLine <= endLine && chunk.endLine >= startLine) { chunk.startLine = Math.min(chunk.startLine, startLine); chunk.endLine = Math.max(chunk.endLine, endLine); return; } if (chunk.startLine > endLine) { this._scheduledPaintLines.splice(i, 0, { startLine: startLine, endLine: endLine }); return; } } this._scheduledPaintLines.push({ startLine: startLine, endLine: endLine }); } }, _paintScheduledLines: function(skipRestoreSelection) { if (this._paintScheduledLinesTimer) clearTimeout(this._paintScheduledLinesTimer); delete this._paintScheduledLinesTimer; if (!this._scheduledPaintLines) return; if (this._dirtyLines || this._repaintAllTimer) { this._paintScheduledLinesTimer = setTimeout(this._paintScheduledLines.bind(this), 50); return; } var scheduledPaintLines = this._scheduledPaintLines; delete this._scheduledPaintLines; this._restorePaintLinesOperationsCredit(); this._paintLineChunks(scheduledPaintLines, !skipRestoreSelection); this._adjustPaintLinesOperationsRefreshValue(); }, _restorePaintLinesOperationsCredit: function() { if (!this._paintLinesOperationsRefreshValue) this._paintLinesOperationsRefreshValue = 250; this._paintLinesOperationsCredit = this._paintLinesOperationsRefreshValue; this._paintLinesOperationsLastRefresh = Date.now(); }, _adjustPaintLinesOperationsRefreshValue: function() { var operationsDone = this._paintLinesOperationsRefreshValue - this._paintLinesOperationsCredit; if (operationsDone <= 0) return; var timePast = Date.now() - this._paintLinesOperationsLastRefresh; if (timePast <= 0) return; var value = Math.floor(operationsDone / timePast * 50); this._paintLinesOperationsRefreshValue = Number.constrain(value, 150, 1500); }, _paintLines: function(fromLine, toLine, restoreSelection) { this._paintLineChunks([ { startLine: fromLine, endLine: toLine } ], restoreSelection); }, _paintLineChunks: function(lineChunks, restoreSelection) { var visibleFrom = this.element.scrollTop; var firstVisibleLineNumber = this._findFirstVisibleLineNumber(visibleFrom); var chunk; var selection; var invisibleLineRows = []; for (var i = 0; i < lineChunks.length; ++i) { var lineChunk = lineChunks[i]; if (this._dirtyLines || this._scheduledPaintLines) { this._schedulePaintLines(lineChunk.startLine, lineChunk.endLine); continue; } for (var lineNumber = lineChunk.startLine; lineNumber < lineChunk.endLine; ++lineNumber) { if (!chunk || lineNumber < chunk.startLine || lineNumber >= chunk.startLine + chunk.linesCount) chunk = this.chunkForLine(lineNumber); var lineRow = chunk.getExpandedLineRow(lineNumber); if (!lineRow) continue; if (lineNumber < firstVisibleLineNumber) { invisibleLineRows.push(lineRow); continue; } if (restoreSelection && !selection) selection = this._getSelection(); this._paintLine(lineRow); if (this._paintLinesOperationsCredit < 0) { this._schedulePaintLines(lineNumber + 1, lineChunk.endLine); break; } } } for (var i = 0; i < invisibleLineRows.length; ++i) { if (restoreSelection && !selection) selection = this._getSelection(); this._paintLine(invisibleLineRows[i]); } if (restoreSelection) this._restoreSelection(selection); }, _paintLine: function(lineRow) { var lineNumber = lineRow.lineNumber; if (this._dirtyLines) { this._schedulePaintLines(lineNumber, lineNumber + 1); return; } this.beginDomUpdates(); try { if (this._scheduledPaintLines || this._paintLinesOperationsCredit < 0) { this._schedulePaintLines(lineNumber, lineNumber + 1); return; } var highlight = this._textModel.getAttribute(lineNumber, "highlight"); if (!highlight) return; var decorationsElement = lineRow.decorationsElement; if (!decorationsElement) lineRow.removeChildren(); else { while (true) { var child = lineRow.firstChild; if (!child || child === decorationsElement) break; lineRow.removeChild(child); } } var line = this._textModel.line(lineNumber); if (!line) lineRow.insertBefore(document.createElement("br"), decorationsElement); var plainTextStart = -1; for (var j = 0; j < line.length;) { if (j > 1000) { if (plainTextStart === -1) plainTextStart = j; break; } var attribute = highlight[j]; if (!attribute || !attribute.tokenType) { if (plainTextStart === -1) plainTextStart = j; j++; } else { if (plainTextStart !== -1) { this._insertTextNodeBefore(lineRow, decorationsElement, line.substring(plainTextStart, j)); plainTextStart = -1; --this._paintLinesOperationsCredit; } this._insertSpanBefore(lineRow, decorationsElement, line.substring(j, j + attribute.length), attribute.tokenType); j += attribute.length; --this._paintLinesOperationsCredit; } } if (plainTextStart !== -1) { this._insertTextNodeBefore(lineRow, decorationsElement, line.substring(plainTextStart, line.length)); --this._paintLinesOperationsCredit; } } finally { if (this._rangeToMark && this._rangeToMark.startLine === lineNumber) this._markedRangeElement = WebInspector.highlightSearchResult(lineRow, this._rangeToMark.startColumn, this._rangeToMark.endColumn - this._rangeToMark.startColumn); this.endDomUpdates(); } }, _releaseLinesHighlight: function(lineRow) { if (!lineRow) return; if ("spans" in lineRow) { var spans = lineRow.spans; for (var j = 0; j < spans.length; ++j) this._cachedSpans.push(spans[j]); delete lineRow.spans; } if ("textNodes" in lineRow) { var textNodes = lineRow.textNodes; for (var j = 0; j < textNodes.length; ++j) this._cachedTextNodes.push(textNodes[j]); delete lineRow.textNodes; } this._cachedRows.push(lineRow); }, _getSelection: function() { var selection = window.getSelection(); if (!selection.rangeCount) return null; if (!this._container.isAncestor(selection.anchorNode) || !this._container.isAncestor(selection.focusNode)) return null; var start = this._selectionToPosition(selection.anchorNode, selection.anchorOffset); var end = selection.isCollapsed ? start : this._selectionToPosition(selection.focusNode, selection.focusOffset); return new WebInspector.TextRange(start.line, start.column, end.line, end.column); }, _restoreSelection: function(range, scrollIntoView) { if (!range) return; var start = this._positionToSelection(range.startLine, range.startColumn); var end = range.isEmpty() ? start : this._positionToSelection(range.endLine, range.endColumn); window.getSelection().setBaseAndExtent(start.container, start.offset, end.container, end.offset); if (scrollIntoView) { for (var node = end.container; node; node = node.parentElement) { if (node.scrollIntoViewIfNeeded) { node.scrollIntoViewIfNeeded(); break; } } } }, _selectionToPosition: function(container, offset) { if (container === this._container && offset === 0) return { line: 0, column: 0 }; if (container === this._container && offset === 1) return { line: this._textModel.linesCount - 1, column: this._textModel.lineLength(this._textModel.linesCount - 1) }; var lineRow = this._enclosingLineRowOrSelf(container); var lineNumber = lineRow.lineNumber; if (container === lineRow && offset === 0) return { line: lineNumber, column: 0 }; var column = 0; var node = lineRow.nodeType === Node.TEXT_NODE ? lineRow : lineRow.traverseNextTextNode(lineRow); while (node && node !== container) { var text = node.textContent; for (var i = 0; i < text.length; ++i) { if (text.charAt(i) === "\n") { lineNumber++; column = 0; } else column++; } node = node.traverseNextTextNode(lineRow); } if (node === container && offset) { var text = node.textContent; for (var i = 0; i < offset; ++i) { if (text.charAt(i) === "\n") { lineNumber++; column = 0; } else column++; } } return { line: lineNumber, column: column }; }, _positionToSelection: function(line, column) { var chunk = this.chunkForLine(line); var lineRow = chunk.linesCount === 1 ? chunk.element : chunk.getExpandedLineRow(line); if (lineRow) var rangeBoundary = lineRow.rangeBoundaryForOffset(column); else { var offset = column; for (var i = chunk.startLine; i < line && i < this._textModel.linesCount; ++i) offset += this._textModel.lineLength(i) + 1; lineRow = chunk.element; if (lineRow.firstChild) var rangeBoundary = { container: lineRow.firstChild, offset: offset }; else var rangeBoundary = { container: lineRow, offset: 0 }; } return rangeBoundary; }, _enclosingLineRowOrSelf: function(element) { var lineRow = element.enclosingNodeOrSelfWithClass("webkit-line-content"); if (lineRow) return lineRow; for (lineRow = element; lineRow; lineRow = lineRow.parentElement) { if (lineRow.parentElement === this._container) return lineRow; } return null; }, _insertSpanBefore: function(element, oldChild, content, className) { if (className === "html-resource-link" || className === "html-external-link") { element.insertBefore(this._createLink(content, className === "html-external-link"), oldChild); return; } var span = this._cachedSpans.pop() || document.createElement("span"); span.className = "webkit-" + className; span.textContent = content; element.insertBefore(span, oldChild); if (!("spans" in element)) element.spans = []; element.spans.push(span); }, _insertTextNodeBefore: function(element, oldChild, text) { var textNode = this._cachedTextNodes.pop(); if (textNode) textNode.nodeValue = text; else textNode = document.createTextNode(text); element.insertBefore(textNode, oldChild); if (!("textNodes" in element)) element.textNodes = []; element.textNodes.push(textNode); }, _createLink: function(content, isExternal) { var quote = content.charAt(0); if (content.length > 1 && (quote === "\"" || quote === "'")) content = content.substring(1, content.length - 1); else quote = null; var span = document.createElement("span"); span.className = "webkit-html-attribute-value"; if (quote) span.appendChild(document.createTextNode(quote)); span.appendChild(this._delegate.createLink(content, isExternal)); if (quote) span.appendChild(document.createTextNode(quote)); return span; }, _handleDOMUpdates: function(e) { if (this._domUpdateCoalescingLevel) return; var target = e.target; if (target === this._container) return; var lineRow = this._enclosingLineRowOrSelf(target); if (!lineRow) return; if (lineRow.decorationsElement && lineRow.decorationsElement.isSelfOrAncestor(target)) { if (this._syncDecorationsForLineListener) this._syncDecorationsForLineListener(lineRow.lineNumber); return; } if (this._readOnly) return; if (target === lineRow && e.type === "DOMNodeInserted") { delete lineRow.lineNumber; } var startLine = 0; for (var row = lineRow; row; row = row.previousSibling) { if (typeof row.lineNumber === "number") { startLine = row.lineNumber; break; } } var endLine = startLine + 1; for (var row = lineRow.nextSibling; row; row = row.nextSibling) { if (typeof row.lineNumber === "number" && row.lineNumber > startLine) { endLine = row.lineNumber; break; } } if (this._dirtyLines) { this._dirtyLines.start = Math.min(this._dirtyLines.start, startLine); this._dirtyLines.end = Math.max(this._dirtyLines.end, endLine); } else { this._dirtyLines = { start: startLine, end: endLine }; setTimeout(this._applyDomUpdates.bind(this), 0); this.markAndRevealRange(null); } }, _applyDomUpdates: function() { if (!this._dirtyLines) return; if (this._readOnly) { delete this._dirtyLines; return; } var dirtyLines = this._dirtyLines; var firstChunkNumber = this._chunkNumberForLine(dirtyLines.start); var startLine = this._textChunks[firstChunkNumber].startLine; var endLine = this._textModel.linesCount; var firstLineRow; if (firstChunkNumber) { var chunk = this._textChunks[firstChunkNumber - 1]; firstLineRow = chunk.expanded ? chunk.getExpandedLineRow(chunk.startLine + chunk.linesCount - 1) : chunk.element; firstLineRow = firstLineRow.nextSibling; } else firstLineRow = this._container.firstChild; var lines = []; for (var lineRow = firstLineRow; lineRow; lineRow = lineRow.nextSibling) { if (typeof lineRow.lineNumber === "number" && lineRow.lineNumber >= dirtyLines.end) { endLine = lineRow.lineNumber; break; } lineRow.lineNumber = startLine + lines.length; this._collectLinesFromDiv(lines, lineRow); } var startOffset = 0; while (startLine < dirtyLines.start && startOffset < lines.length) { if (this._textModel.line(startLine) !== lines[startOffset]) break; ++startOffset; ++startLine; } var endOffset = lines.length; while (endLine > dirtyLines.end && endOffset > startOffset) { if (this._textModel.line(endLine - 1) !== lines[endOffset - 1]) break; --endOffset; --endLine; } lines = lines.slice(startOffset, endOffset); var startColumn = 0; var endColumn = this._textModel.lineLength(endLine - 1); if (lines.length > 0) { var line1 = this._textModel.line(startLine); var line2 = lines[0]; while (line1[startColumn] && line1[startColumn] === line2[startColumn]) ++startColumn; lines[0] = line2.substring(startColumn); line1 = this._textModel.line(endLine - 1); line2 = lines[lines.length - 1]; for (var i = 0; i < endColumn && i < line2.length; ++i) { if (startLine === endLine - 1 && endColumn - i <= startColumn) break; if (line1[endColumn - i - 1] !== line2[line2.length - i - 1]) break; } if (i) { endColumn -= i; lines[lines.length - 1] = line2.substring(0, line2.length - i); } } var selection = this._getSelection(); if (lines.length === 0 && endLine < this._textModel.linesCount) var oldRange = new WebInspector.TextRange(startLine, 0, endLine, 0); else if (lines.length === 0 && startLine > 0) var oldRange = new WebInspector.TextRange(startLine - 1, this._textModel.lineLength(startLine - 1), endLine - 1, this._textModel.lineLength(endLine - 1)); else var oldRange = new WebInspector.TextRange(startLine, startColumn, endLine - 1, endColumn); var newContent = lines.join("\n"); if (this._textModel.copyRange(oldRange) === newContent) { delete this._dirtyLines; return; } if (lines.length === 1 && lines[0] === "}" && oldRange.isEmpty() && selection.isEmpty() && !this._textModel.line(oldRange.endLine).trim()) this._unindentAfterBlock(oldRange, selection); this._enterTextChangeMode(); delete this._dirtyLines; var newRange = this._editRange(oldRange, newContent); this._paintScheduledLines(true); this._restoreSelection(selection); this._exitTextChangeMode(oldRange, newRange); }, _unindentAfterBlock: function(oldRange, selection) { var nestingLevel = 1; for (var i = oldRange.endLine; i >= 0; --i) { var attribute = this._textModel.getAttribute(i, "highlight"); if (!attribute) continue; var columnNumbers = Object.keys(attribute).reverse(); for (var j = 0; j < columnNumbers.length; ++j) { var column = columnNumbers[j]; if (attribute[column].tokenType === "block-start") { if (!(--nestingLevel)) { var lineContent = this._textModel.line(i); var blockOffset = lineContent.length - lineContent.trimLeft().length; if (blockOffset < oldRange.startColumn) { oldRange.startColumn = blockOffset; selection.startColumn = blockOffset + 1; selection.endColumn = blockOffset + 1; } return; } } if (attribute[column].tokenType === "block-end") ++nestingLevel; } } }, textChanged: function(oldRange, newRange) { this.beginDomUpdates(); this._removeDecorationsInRange(oldRange); this._updateChunksForRanges(oldRange, newRange); this._updateHighlightsForRange(newRange); this.endDomUpdates(); }, _editRange: function(range, text) { if (this._lastEditedRange && (!text || text.indexOf("\n") !== -1 || this._lastEditedRange.endLine !== range.startLine || this._lastEditedRange.endColumn !== range.startColumn)) this._textModel.markUndoableState(); var newRange = this._textModel.editRange(range, text); this._lastEditedRange = newRange; return newRange; }, _removeDecorationsInRange: function(range) { for (var i = this._chunkNumberForLine(range.startLine); i < this._textChunks.length; ++i) { var chunk = this._textChunks[i]; if (chunk.startLine > range.endLine) break; chunk.removeAllDecorations(); } }, _updateChunksForRanges: function(oldRange, newRange) { var firstChunkNumber = this._chunkNumberForLine(oldRange.startLine); var lastChunkNumber = firstChunkNumber; while (lastChunkNumber + 1 < this._textChunks.length) { if (this._textChunks[lastChunkNumber + 1].startLine > oldRange.endLine) break; ++lastChunkNumber; } var startLine = this._textChunks[firstChunkNumber].startLine; var linesCount = this._textChunks[lastChunkNumber].startLine + this._textChunks[lastChunkNumber].linesCount - startLine; var linesDiff = newRange.linesCount - oldRange.linesCount; linesCount += linesDiff; if (linesDiff) { for (var chunkNumber = lastChunkNumber + 1; chunkNumber < this._textChunks.length; ++chunkNumber) this._textChunks[chunkNumber].startLine += linesDiff; } var firstLineRow; if (firstChunkNumber) { var chunk = this._textChunks[firstChunkNumber - 1]; firstLineRow = chunk.expanded ? chunk.getExpandedLineRow(chunk.startLine + chunk.linesCount - 1) : chunk.element; firstLineRow = firstLineRow.nextSibling; } else firstLineRow = this._container.firstChild; for (var chunkNumber = firstChunkNumber; chunkNumber <= lastChunkNumber; ++chunkNumber) { var chunk = this._textChunks[chunkNumber]; if (chunk.startLine + chunk.linesCount > this._textModel.linesCount) break; var lineNumber = chunk.startLine; for (var lineRow = firstLineRow; lineRow && lineNumber < chunk.startLine + chunk.linesCount; lineRow = lineRow.nextSibling) { if (lineRow.lineNumber !== lineNumber || lineRow !== chunk.getExpandedLineRow(lineNumber) || lineRow.textContent !== this._textModel.line(lineNumber) || !lineRow.firstChild) break; ++lineNumber; } if (lineNumber < chunk.startLine + chunk.linesCount) break; chunk.updateCollapsedLineRow(); ++firstChunkNumber; firstLineRow = lineRow; startLine += chunk.linesCount; linesCount -= chunk.linesCount; } if (firstChunkNumber > lastChunkNumber && linesCount === 0) return; var chunk = this._textChunks[lastChunkNumber + 1]; var linesInLastChunk = linesCount % this._defaultChunkSize; if (chunk && !chunk.decorated && linesInLastChunk > 0 && linesInLastChunk + chunk.linesCount <= this._defaultChunkSize) { ++lastChunkNumber; linesCount += chunk.linesCount; } var scrollTop = this.element.scrollTop; var scrollLeft = this.element.scrollLeft; var firstUnmodifiedLineRow = null; chunk = this._textChunks[lastChunkNumber + 1]; if (chunk) firstUnmodifiedLineRow = chunk.expanded ? chunk.getExpandedLineRow(chunk.startLine) : chunk.element; while (firstLineRow && firstLineRow !== firstUnmodifiedLineRow) { var lineRow = firstLineRow; firstLineRow = firstLineRow.nextSibling; this._container.removeChild(lineRow); } for (var chunkNumber = firstChunkNumber; linesCount > 0; ++chunkNumber) { var chunkLinesCount = Math.min(this._defaultChunkSize, linesCount); var newChunk = this._createNewChunk(startLine, startLine + chunkLinesCount); this._container.insertBefore(newChunk.element, firstUnmodifiedLineRow); if (chunkNumber <= lastChunkNumber) this._textChunks[chunkNumber] = newChunk; else this._textChunks.splice(chunkNumber, 0, newChunk); startLine += chunkLinesCount; linesCount -= chunkLinesCount; } if (chunkNumber <= lastChunkNumber) this._textChunks.splice(chunkNumber, lastChunkNumber - chunkNumber + 1); this.element.scrollTop = scrollTop; this.element.scrollLeft = scrollLeft; }, _updateHighlightsForRange: function(range) { var visibleFrom = this.element.scrollTop; var visibleTo = this.element.scrollTop + this.element.clientHeight; var result = this._findVisibleChunks(visibleFrom, visibleTo); var chunk = this._textChunks[result.end - 1]; var lastVisibleLine = chunk.startLine + chunk.linesCount; lastVisibleLine = Math.max(lastVisibleLine, range.endLine + 1); lastVisibleLine = Math.min(lastVisibleLine, this._textModel.linesCount); var updated = this._highlighter.updateHighlight(range.startLine, lastVisibleLine); if (!updated) { for (var i = this._chunkNumberForLine(range.startLine); i < this._textChunks.length; ++i) this._textChunks[i].expanded = false; } this._repaintAll(); }, _collectLinesFromDiv: function(lines, element) { var textContents = []; var node = element.nodeType === Node.TEXT_NODE ? element : element.traverseNextNode(element); while (node) { if (element.decorationsElement === node) { node = node.nextSibling; continue; } if (node.nodeName.toLowerCase() === "br") textContents.push("\n"); else if (node.nodeType === Node.TEXT_NODE) textContents.push(node.textContent); node = node.traverseNextNode(element); } var textContent = textContents.join(""); textContent = textContent.replace(/\n$/, ""); textContents = textContent.split("\n"); for (var i = 0; i < textContents.length; ++i) lines.push(textContents[i]); }, __proto__: WebInspector.TextEditorChunkedPanel.prototype } WebInspector.TextEditorMainChunk = function(chunkedPanel, startLine, endLine) { this._chunkedPanel = chunkedPanel; this._textModel = chunkedPanel._textModel; this.element = document.createElement("div"); this.element.lineNumber = startLine; this.element.className = "webkit-line-content"; this._startLine = startLine; endLine = Math.min(this._textModel.linesCount, endLine); this.linesCount = endLine - startLine; this._expanded = false; this._readOnly = false; this.updateCollapsedLineRow(); } WebInspector.TextEditorMainChunk.prototype = { addDecoration: function(decoration) { this._chunkedPanel.beginDomUpdates(); if (typeof decoration === "string") this.element.addStyleClass(decoration); else { if (!this.element.decorationsElement) { this.element.decorationsElement = document.createElement("div"); this.element.decorationsElement.className = "webkit-line-decorations"; this.element.appendChild(this.element.decorationsElement); } this.element.decorationsElement.appendChild(decoration); } this._chunkedPanel.endDomUpdates(); }, removeDecoration: function(decoration) { this._chunkedPanel.beginDomUpdates(); if (typeof decoration === "string") this.element.removeStyleClass(decoration); else if (this.element.decorationsElement) this.element.decorationsElement.removeChild(decoration); this._chunkedPanel.endDomUpdates(); }, removeAllDecorations: function() { this._chunkedPanel.beginDomUpdates(); this.element.className = "webkit-line-content"; if (this.element.decorationsElement) { this.element.removeChild(this.element.decorationsElement); delete this.element.decorationsElement; } this._chunkedPanel.endDomUpdates(); }, get decorated() { return this.element.className !== "webkit-line-content" || !!(this.element.decorationsElement && this.element.decorationsElement.firstChild); }, get startLine() { return this._startLine; }, set startLine(startLine) { this._startLine = startLine; this.element.lineNumber = startLine; if (this._expandedLineRows) { for (var i = 0; i < this._expandedLineRows.length; ++i) this._expandedLineRows[i].lineNumber = startLine + i; } }, get expanded() { return this._expanded; }, set expanded(expanded) { if (this._expanded === expanded) return; this._expanded = expanded; if (this.linesCount === 1) { if (expanded) this._chunkedPanel._paintLine(this.element); return; } this._chunkedPanel.beginDomUpdates(); if (expanded) { this._expandedLineRows = []; var parentElement = this.element.parentElement; for (var i = this.startLine; i < this.startLine + this.linesCount; ++i) { var lineRow = this._createRow(i); this._updateElementReadOnlyState(lineRow); parentElement.insertBefore(lineRow, this.element); this._expandedLineRows.push(lineRow); } parentElement.removeChild(this.element); this._chunkedPanel._paintLines(this.startLine, this.startLine + this.linesCount); } else { var elementInserted = false; for (var i = 0; i < this._expandedLineRows.length; ++i) { var lineRow = this._expandedLineRows[i]; var parentElement = lineRow.parentElement; if (parentElement) { if (!elementInserted) { elementInserted = true; parentElement.insertBefore(this.element, lineRow); } parentElement.removeChild(lineRow); } this._chunkedPanel._releaseLinesHighlight(lineRow); } delete this._expandedLineRows; } this._chunkedPanel.endDomUpdates(); }, set readOnly(readOnly) { if (this._readOnly === readOnly) return; this._readOnly = readOnly; this._updateElementReadOnlyState(this.element); if (this._expandedLineRows) { for (var i = 0; i < this._expandedLineRows.length; ++i) this._updateElementReadOnlyState(this._expandedLineRows[i]); } }, get readOnly() { return this._readOnly; }, _updateElementReadOnlyState: function(element) { if (this._readOnly) element.addStyleClass("text-editor-read-only"); else element.removeStyleClass("text-editor-read-only"); }, get height() { if (!this._expandedLineRows) return this._chunkedPanel._totalHeight(this.element); return this._chunkedPanel._totalHeight(this._expandedLineRows[0], this._expandedLineRows[this._expandedLineRows.length - 1]); }, get offsetTop() { return (this._expandedLineRows && this._expandedLineRows.length) ? this._expandedLineRows[0].offsetTop : this.element.offsetTop; }, _createRow: function(lineNumber) { var lineRow = this._chunkedPanel._cachedRows.pop() || document.createElement("div"); lineRow.lineNumber = lineNumber; lineRow.className = "webkit-line-content"; lineRow.textContent = this._textModel.line(lineNumber); if (!lineRow.textContent) lineRow.appendChild(document.createElement("br")); return lineRow; }, getExpandedLineRow: function(lineNumber) { if (!this._expanded || lineNumber < this.startLine || lineNumber >= this.startLine + this.linesCount) return null; if (!this._expandedLineRows) return this.element; return this._expandedLineRows[lineNumber - this.startLine]; }, updateCollapsedLineRow: function() { if (this.linesCount === 1 && this._expanded) return; var lines = []; for (var i = this.startLine; i < this.startLine + this.linesCount; ++i) lines.push(this._textModel.line(i)); this.element.removeChildren(); this.element.textContent = lines.join("\n"); if (!lines[lines.length - 1]) this.element.appendChild(document.createElement("br")); } } WebInspector.SourceFrame = function(contentProvider) { WebInspector.View.call(this); this.element.addStyleClass("script-view"); this._url = contentProvider.contentURL(); this._contentProvider = contentProvider; var textEditorDelegate = new WebInspector.TextEditorDelegateForSourceFrame(this); if (WebInspector.experimentsSettings.codemirror.isEnabled()) { importScript("CodeMirrorTextEditor.js"); this._textEditor = new WebInspector.CodeMirrorTextEditor(this._url, textEditorDelegate); } else this._textEditor = new WebInspector.DefaultTextEditor(this._url, textEditorDelegate); this._currentSearchResultIndex = -1; this._searchResults = []; this._messages = []; this._rowMessages = {}; this._messageBubbles = {}; this._textEditor.setReadOnly(!this.canEditSource()); this._shortcuts = {}; this._shortcuts[WebInspector.KeyboardShortcut.makeKey("s", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)] = this._commitEditing.bind(this); this.element.addEventListener("keydown", this._handleKeyDown.bind(this), false); } WebInspector.SourceFrame.createSearchRegex = function(query, modifiers) { var regex; modifiers = modifiers || ""; try { if (/^\/.*\/$/.test(query)) regex = new RegExp(query.substring(1, query.length - 1), modifiers); } catch (e) { } if (!regex) regex = createPlainTextSearchRegex(query, "i" + modifiers); return regex; } WebInspector.SourceFrame.Events = { ScrollChanged: "ScrollChanged", SelectionChanged: "SelectionChanged" } WebInspector.SourceFrame.prototype = { wasShown: function() { this._ensureContentLoaded(); this._textEditor.show(this.element); this._wasShownOrLoaded(); }, willHide: function() { WebInspector.View.prototype.willHide.call(this); this._clearLineHighlight(); this._clearLineToReveal(); }, statusBarItems: function() { return []; }, defaultFocusedElement: function() { return this._textEditor.defaultFocusedElement(); }, get loaded() { return this._loaded; }, hasContent: function() { return true; }, get textEditor() { return this._textEditor; }, _ensureContentLoaded: function() { if (!this._contentRequested) { this._contentRequested = true; this._contentProvider.requestContent(this.setContent.bind(this)); } }, addMessage: function(msg) { this._messages.push(msg); if (this.loaded) this.addMessageToSource(msg.line - 1, msg); }, clearMessages: function() { for (var line in this._messageBubbles) { var bubble = this._messageBubbles[line]; bubble.parentNode.removeChild(bubble); } this._messages = []; this._rowMessages = {}; this._messageBubbles = {}; this._textEditor.doResize(); }, canHighlightLine: function(line) { return true; }, highlightLine: function(line) { this._clearLineToReveal(); this._clearLineToScrollTo(); this._lineToHighlight = line; this._innerHighlightLineIfNeeded(); this._textEditor.setSelection(WebInspector.TextRange.createFromLocation(line, 0)); }, _innerHighlightLineIfNeeded: function() { if (typeof this._lineToHighlight === "number") { if (this.loaded && this._textEditor.isShowing()) { this._textEditor.highlightLine(this._lineToHighlight); delete this._lineToHighlight } } }, _clearLineHighlight: function() { this._textEditor.clearLineHighlight(); delete this._lineToHighlight; }, revealLine: function(line) { this._clearLineHighlight(); this._clearLineToScrollTo(); this._lineToReveal = line; this._innerRevealLineIfNeeded(); }, _innerRevealLineIfNeeded: function() { if (typeof this._lineToReveal === "number") { if (this.loaded && this._textEditor.isShowing()) { this._textEditor.revealLine(this._lineToReveal); delete this._lineToReveal } } }, _clearLineToReveal: function() { delete this._lineToReveal; }, scrollToLine: function(line) { this._clearLineHighlight(); this._clearLineToReveal(); this._lineToScrollTo = line; this._innerScrollToLineIfNeeded(); }, _innerScrollToLineIfNeeded: function() { if (typeof this._lineToScrollTo === "number") { if (this.loaded && this._textEditor.isShowing()) { this._textEditor.scrollToLine(this._lineToScrollTo); delete this._lineToScrollTo } } }, _clearLineToScrollTo: function() { delete this._lineToScrollTo; }, setSelection: function(textRange) { this._selectionToSet = textRange; this._innerSetSelectionIfNeeded(); }, _innerSetSelectionIfNeeded: function() { if (this._selectionToSet && this.loaded && this._textEditor.isShowing()) { this._textEditor.setSelection(this._selectionToSet); delete this._selectionToSet; } }, _wasShownOrLoaded: function() { this._innerHighlightLineIfNeeded(); this._innerRevealLineIfNeeded(); this._innerScrollToLineIfNeeded(); this._innerSetSelectionIfNeeded(); }, onTextChanged: function(oldRange, newRange) { if (!this._isReplacing) WebInspector.searchController.cancelSearch(); this.clearMessages(); }, setContent: function(content, contentEncoded, mimeType) { this._textEditor.mimeType = mimeType; this._loaded = true; this._textEditor.setText(content || ""); this._textEditor.beginUpdates(); this._setTextEditorDecorations(); this._wasShownOrLoaded(); if (this._delayedFindSearchMatches) { this._delayedFindSearchMatches(); delete this._delayedFindSearchMatches; } this.onTextEditorContentLoaded(); this._textEditor.endUpdates(); }, onTextEditorContentLoaded: function() {}, _setTextEditorDecorations: function() { this._rowMessages = {}; this._messageBubbles = {}; this._textEditor.beginUpdates(); this._addExistingMessagesToSource(); this._textEditor.doResize(); this._textEditor.endUpdates(); }, performSearch: function(query, callback) { this.searchCanceled(); function doFindSearchMatches(query) { this._currentSearchResultIndex = -1; this._searchResults = []; var regex = WebInspector.SourceFrame.createSearchRegex(query); this._searchResults = this._collectRegexMatches(regex); var shiftToIndex = 0; var selection = this._textEditor.lastSelection(); for (var i = 0; selection && i < this._searchResults.length; ++i) { if (this._searchResults[i].compareTo(selection) >= 0) { shiftToIndex = i; break; } } if (shiftToIndex) this._searchResults = this._searchResults.rotate(shiftToIndex); callback(this, this._searchResults.length); } if (this.loaded) doFindSearchMatches.call(this, query); else this._delayedFindSearchMatches = doFindSearchMatches.bind(this, query); this._ensureContentLoaded(); }, searchCanceled: function() { delete this._delayedFindSearchMatches; if (!this.loaded) return; this._currentSearchResultIndex = -1; this._searchResults = []; this._textEditor.markAndRevealRange(null); }, hasSearchResults: function() { return this._searchResults.length > 0; }, jumpToFirstSearchResult: function() { this.jumpToSearchResult(0); }, jumpToLastSearchResult: function() { this.jumpToSearchResult(this._searchResults.length - 1); }, jumpToNextSearchResult: function() { this.jumpToSearchResult(this._currentSearchResultIndex + 1); }, jumpToPreviousSearchResult: function() { this.jumpToSearchResult(this._currentSearchResultIndex - 1); }, showingFirstSearchResult: function() { return this._searchResults.length && this._currentSearchResultIndex === 0; }, showingLastSearchResult: function() { return this._searchResults.length && this._currentSearchResultIndex === (this._searchResults.length - 1); }, get currentSearchResultIndex() { return this._currentSearchResultIndex; }, jumpToSearchResult: function(index) { if (!this.loaded || !this._searchResults.length) return; this._currentSearchResultIndex = (index + this._searchResults.length) % this._searchResults.length; this._textEditor.markAndRevealRange(this._searchResults[this._currentSearchResultIndex]); }, replaceSearchMatchWith: function(text) { var range = this._searchResults[this._currentSearchResultIndex]; if (!range) return; this._textEditor.markAndRevealRange(null); this._isReplacing = true; var newRange = this._textEditor.editRange(range, text); delete this._isReplacing; this._textEditor.setSelection(newRange.collapseToEnd()); }, replaceAllWith: function(query, replacement) { this._textEditor.markAndRevealRange(null); var text = this._textEditor.text(); var range = this._textEditor.range(); text = text.replace(WebInspector.SourceFrame.createSearchRegex(query, "g"), replacement); this._isReplacing = true; this._textEditor.editRange(range, text); delete this._isReplacing; }, _collectRegexMatches: function(regexObject) { var ranges = []; for (var i = 0; i < this._textEditor.linesCount; ++i) { var line = this._textEditor.line(i); var offset = 0; do { var match = regexObject.exec(line); if (match) { if (match[0].length) ranges.push(new WebInspector.TextRange(i, offset + match.index, i, offset + match.index + match[0].length)); offset += match.index + 1; line = line.substring(match.index + 1); } } while (match && line); } return ranges; }, _addExistingMessagesToSource: function() { var length = this._messages.length; for (var i = 0; i < length; ++i) this.addMessageToSource(this._messages[i].line - 1, this._messages[i]); }, addMessageToSource: function(lineNumber, msg) { if (lineNumber >= this._textEditor.linesCount) lineNumber = this._textEditor.linesCount - 1; if (lineNumber < 0) lineNumber = 0; var messageBubbleElement = this._messageBubbles[lineNumber]; if (!messageBubbleElement || messageBubbleElement.nodeType !== Node.ELEMENT_NODE || !messageBubbleElement.hasStyleClass("webkit-html-message-bubble")) { messageBubbleElement = document.createElement("div"); messageBubbleElement.className = "webkit-html-message-bubble"; this._messageBubbles[lineNumber] = messageBubbleElement; this._textEditor.addDecoration(lineNumber, messageBubbleElement); } var rowMessages = this._rowMessages[lineNumber]; if (!rowMessages) { rowMessages = []; this._rowMessages[lineNumber] = rowMessages; } for (var i = 0; i < rowMessages.length; ++i) { if (rowMessages[i].consoleMessage.isEqual(msg)) { rowMessages[i].repeatCount = msg.totalRepeatCount; this._updateMessageRepeatCount(rowMessages[i]); return; } } var rowMessage = { consoleMessage: msg }; rowMessages.push(rowMessage); var imageURL; switch (msg.level) { case WebInspector.ConsoleMessage.MessageLevel.Error: messageBubbleElement.addStyleClass("webkit-html-error-message"); imageURL = "Images/errorIcon.png"; break; case WebInspector.ConsoleMessage.MessageLevel.Warning: messageBubbleElement.addStyleClass("webkit-html-warning-message"); imageURL = "Images/warningIcon.png"; break; } var messageLineElement = document.createElement("div"); messageLineElement.className = "webkit-html-message-line"; messageBubbleElement.appendChild(messageLineElement); var image = document.createElement("img"); image.src = imageURL; image.className = "webkit-html-message-icon"; messageLineElement.appendChild(image); messageLineElement.appendChild(document.createTextNode(msg.message)); rowMessage.element = messageLineElement; rowMessage.repeatCount = msg.totalRepeatCount; this._updateMessageRepeatCount(rowMessage); }, _updateMessageRepeatCount: function(rowMessage) { if (rowMessage.repeatCount < 2) return; if (!rowMessage.repeatCountElement) { var repeatCountElement = document.createElement("span"); rowMessage.element.appendChild(repeatCountElement); rowMessage.repeatCountElement = repeatCountElement; } rowMessage.repeatCountElement.textContent = WebInspector.UIString(" (repeated %d times)", rowMessage.repeatCount); }, removeMessageFromSource: function(lineNumber, msg) { if (lineNumber >= this._textEditor.linesCount) lineNumber = this._textEditor.linesCount - 1; if (lineNumber < 0) lineNumber = 0; var rowMessages = this._rowMessages[lineNumber]; for (var i = 0; rowMessages && i < rowMessages.length; ++i) { var rowMessage = rowMessages[i]; if (rowMessage.consoleMessage !== msg) continue; var messageLineElement = rowMessage.element; var messageBubbleElement = messageLineElement.parentElement; messageBubbleElement.removeChild(messageLineElement); rowMessages.remove(rowMessage); if (!rowMessages.length) delete this._rowMessages[lineNumber]; if (!messageBubbleElement.childElementCount) { this._textEditor.removeDecoration(lineNumber, messageBubbleElement); delete this._messageBubbles[lineNumber]; } break; } }, populateLineGutterContextMenu: function(contextMenu, lineNumber) { }, populateTextAreaContextMenu: function(contextMenu, lineNumber) { }, inheritScrollPositions: function(sourceFrame) { this._textEditor.inheritScrollPositions(sourceFrame._textEditor); }, canEditSource: function() { return false; }, commitEditing: function(text) { }, selectionChanged: function(textRange) { this.dispatchEventToListeners(WebInspector.SourceFrame.Events.SelectionChanged, textRange); }, scrollChanged: function(lineNumber) { this.dispatchEventToListeners(WebInspector.SourceFrame.Events.ScrollChanged, lineNumber); }, _handleKeyDown: function(e) { var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(e); var handler = this._shortcuts[shortcutKey]; if (handler && handler()) e.consume(true); }, _commitEditing: function() { if (this._textEditor.readOnly()) return false; var content = this._textEditor.text(); this.commitEditing(content); return true; }, __proto__: WebInspector.View.prototype } WebInspector.TextEditorDelegateForSourceFrame = function(sourceFrame) { this._sourceFrame = sourceFrame; } WebInspector.TextEditorDelegateForSourceFrame.prototype = { onTextChanged: function(oldRange, newRange) { this._sourceFrame.onTextChanged(oldRange, newRange); }, selectionChanged: function(textRange) { this._sourceFrame.selectionChanged(textRange); }, scrollChanged: function(lineNumber) { this._sourceFrame.scrollChanged(lineNumber); }, populateLineGutterContextMenu: function(contextMenu, lineNumber) { this._sourceFrame.populateLineGutterContextMenu(contextMenu, lineNumber); }, populateTextAreaContextMenu: function(contextMenu, lineNumber) { this._sourceFrame.populateTextAreaContextMenu(contextMenu, lineNumber); }, createLink: function(hrefValue, isExternal) { var targetLocation = WebInspector.ParsedURL.completeURL(this._sourceFrame._url, hrefValue); return WebInspector.linkifyURLAsNode(targetLocation || hrefValue, hrefValue, undefined, isExternal); }, __proto__: WebInspector.TextEditorDelegate.prototype } WebInspector.ResourceView = function(resource) { WebInspector.View.call(this); this.registerRequiredCSS("resourceView.css"); this.element.addStyleClass("resource-view"); this.resource = resource; } WebInspector.ResourceView.prototype = { hasContent: function() { return false; }, __proto__: WebInspector.View.prototype } WebInspector.ResourceView.hasTextContent = function(resource) { if (resource.type.isTextType()) return true; if (resource.type === WebInspector.resourceTypes.Other) return resource.content && !resource.contentEncoded; return false; } WebInspector.ResourceView.nonSourceViewForResource = function(resource) { switch (resource.type) { case WebInspector.resourceTypes.Image: return new WebInspector.ImageView(resource); case WebInspector.resourceTypes.Font: return new WebInspector.FontView(resource); default: return new WebInspector.ResourceView(resource); } } WebInspector.ResourceSourceFrame = function(resource) { this._resource = resource; WebInspector.SourceFrame.call(this, resource); } WebInspector.ResourceSourceFrame.prototype = { get resource() { return this._resource; }, populateTextAreaContextMenu: function(contextMenu, lineNumber) { contextMenu.appendApplicableItems(this._resource); if (this._resource.request) contextMenu.appendApplicableItems(this._resource.request); }, __proto__: WebInspector.SourceFrame.prototype } WebInspector.FontView = function(resource) { WebInspector.ResourceView.call(this, resource); this.element.addStyleClass("font"); } WebInspector.FontView._fontPreviewLines = [ "ABCDEFGHIJKLM", "NOPQRSTUVWXYZ", "abcdefghijklm", "nopqrstuvwxyz", "1234567890" ]; WebInspector.FontView._fontId = 0; WebInspector.FontView._measureFontSize = 50; WebInspector.FontView.prototype = { hasContent: function() { return true; }, _createContentIfNeeded: function() { if (this.fontPreviewElement) return; var uniqueFontName = "WebInspectorFontPreview" + (++WebInspector.FontView._fontId); this.fontStyleElement = document.createElement("style"); this.fontStyleElement.textContent = "@font-face { font-family: \"" + uniqueFontName + "\"; src: url(" + this.resource.url + "); }"; document.head.appendChild(this.fontStyleElement); var fontPreview = document.createElement("div"); for (var i = 0; i < WebInspector.FontView._fontPreviewLines.length; ++i) { if (i > 0) fontPreview.appendChild(document.createElement("br")); fontPreview.appendChild(document.createTextNode(WebInspector.FontView._fontPreviewLines[i])); } this.fontPreviewElement = fontPreview.cloneNode(true); this.fontPreviewElement.style.setProperty("font-family", uniqueFontName); this.fontPreviewElement.style.setProperty("visibility", "hidden"); this._dummyElement = fontPreview; this._dummyElement.style.visibility = "hidden"; this._dummyElement.style.zIndex = "-1"; this._dummyElement.style.display = "inline"; this._dummyElement.style.position = "absolute"; this._dummyElement.style.setProperty("font-family", uniqueFontName); this._dummyElement.style.setProperty("font-size", WebInspector.FontView._measureFontSize + "px"); this.element.appendChild(this.fontPreviewElement); }, wasShown: function() { this._createContentIfNeeded(); this.updateFontPreviewSize(); }, onResize: function() { if (this._inResize) return; this._inResize = true; try { this.updateFontPreviewSize(); } finally { delete this._inResize; } }, _measureElement: function() { this.element.appendChild(this._dummyElement); var result = { width: this._dummyElement.offsetWidth, height: this._dummyElement.offsetHeight }; this.element.removeChild(this._dummyElement); return result; }, updateFontPreviewSize: function() { if (!this.fontPreviewElement || !this.isShowing()) return; this.fontPreviewElement.style.removeProperty("visibility"); var dimension = this._measureElement(); const height = dimension.height; const width = dimension.width; const containerWidth = this.element.offsetWidth - 50; const containerHeight = this.element.offsetHeight - 30; if (!height || !width || !containerWidth || !containerHeight) { this.fontPreviewElement.style.removeProperty("font-size"); return; } var widthRatio = containerWidth / width; var heightRatio = containerHeight / height; var finalFontSize = Math.floor(WebInspector.FontView._measureFontSize * Math.min(widthRatio, heightRatio)) - 2; this.fontPreviewElement.style.setProperty("font-size", finalFontSize + "px", null); }, __proto__: WebInspector.ResourceView.prototype } WebInspector.ImageView = function(resource) { WebInspector.ResourceView.call(this, resource); this.element.addStyleClass("image"); } WebInspector.ImageView.prototype = { hasContent: function() { return true; }, wasShown: function() { this._createContentIfNeeded(); }, _createContentIfNeeded: function() { if (this._container) return; var imageContainer = document.createElement("div"); imageContainer.className = "image"; this.element.appendChild(imageContainer); var imagePreviewElement = document.createElement("img"); imagePreviewElement.addStyleClass("resource-image-view"); imageContainer.appendChild(imagePreviewElement); imagePreviewElement.addEventListener("contextmenu", this._contextMenu.bind(this), true); this._container = document.createElement("div"); this._container.className = "info"; this.element.appendChild(this._container); var imageNameElement = document.createElement("h1"); imageNameElement.className = "title"; imageNameElement.textContent = this.resource.displayName; this._container.appendChild(imageNameElement); var infoListElement = document.createElement("dl"); infoListElement.className = "infoList"; this.resource.populateImageSource(imagePreviewElement); function onImageLoad() { var content = this.resource.content; if (content) var resourceSize = this._base64ToSize(content); else var resourceSize = this.resource.resourceSize; var imageProperties = [ { name: WebInspector.UIString("Dimensions"), value: WebInspector.UIString("%d × %d", imagePreviewElement.naturalWidth, imagePreviewElement.naturalHeight) }, { name: WebInspector.UIString("File size"), value: Number.bytesToString(resourceSize) }, { name: WebInspector.UIString("MIME type"), value: this.resource.mimeType } ]; infoListElement.removeChildren(); for (var i = 0; i < imageProperties.length; ++i) { var dt = document.createElement("dt"); dt.textContent = imageProperties[i].name; infoListElement.appendChild(dt); var dd = document.createElement("dd"); dd.textContent = imageProperties[i].value; infoListElement.appendChild(dd); } var dt = document.createElement("dt"); dt.textContent = WebInspector.UIString("URL"); infoListElement.appendChild(dt); var dd = document.createElement("dd"); var externalResource = true; dd.appendChild(WebInspector.linkifyURLAsNode(this.resource.url, undefined, undefined, externalResource)); infoListElement.appendChild(dd); this._container.appendChild(infoListElement); } imagePreviewElement.addEventListener("load", onImageLoad.bind(this), false); }, _base64ToSize: function(content) { if (!content.length) return 0; var size = (content.length || 0) * 3 / 4; if (content.length > 0 && content[content.length - 1] === "=") size--; if (content.length > 1 && content[content.length - 2] === "=") size--; return size; }, _contextMenu: function(event) { var contextMenu = new WebInspector.ContextMenu(event); contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Copy image URL" : "Copy Image URL"), this._copyImageURL.bind(this)); contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Open image in new tab" : "Open Image in New Tab"), this._openInNewTab.bind(this)); contextMenu.show(); }, _copyImageURL: function(event) { InspectorFrontendHost.copyText(this.resource.url); }, _openInNewTab: function(event) { InspectorFrontendHost.openInNewTab(this.resource.url); }, __proto__: WebInspector.ResourceView.prototype } WebInspector.SplitView = function(isVertical, sidebarSizeSettingName, defaultSidebarSize) { WebInspector.View.call(this); this._isVertical = isVertical; this.registerRequiredCSS("splitView.css"); this.element.className = "split-view"; this._firstElement = document.createElement("div"); this._firstElement.className = "split-view-contents split-view-contents-" + (isVertical ? "vertical" : "horizontal"); if (isVertical) this._firstElement.style.left = 0; else this._firstElement.style.top = 0; this.element.appendChild(this._firstElement); this._secondElement = document.createElement("div"); this._secondElement.className = "split-view-contents split-view-contents-" + (isVertical ? "vertical" : "horizontal"); if (isVertical) this._secondElement.style.right = 0; else this._secondElement.style.bottom = 0; this.element.appendChild(this._secondElement); this._resizerElement = document.createElement("div"); this._resizerElement.className = "split-view-resizer split-view-resizer-" + (isVertical ? "vertical" : "horizontal"); this.installResizer(this._resizerElement); this._resizable = true; this.element.appendChild(this._resizerElement); defaultSidebarSize = defaultSidebarSize || 200; this._savedSidebarSize = defaultSidebarSize; this._sidebarSizeSettingName = sidebarSizeSettingName; if (this._sidebarSizeSettingName) WebInspector.settings[this._sidebarSizeSettingName] = WebInspector.settings.createSetting(this._sidebarSizeSettingName, undefined); this._secondIsSidebar = true; } WebInspector.SplitView.prototype = { firstElement: function() { return this._firstElement; }, secondElement: function() { return this._secondElement; }, setSecondIsSidebar: function(secondIsSidebar) { this._secondIsSidebar = secondIsSidebar; }, resizerElement: function() { return this._resizerElement; }, showOnlyFirst: function() { this._showOnly(this._firstElement, this._secondElement); }, showOnlySecond: function() { this._showOnly(this._secondElement, this._firstElement); }, _showOnly: function(sideA, sideB) { sideA.removeStyleClass("hidden"); sideA.addStyleClass("maximized"); sideB.addStyleClass("hidden"); sideB.removeStyleClass("maximized"); this._removeAllLayoutProperties(); this._firstElement.style.right = 0; this._firstElement.style.bottom = 0; this._firstElement.style.width = "100%"; this._firstElement.style.height = "100%"; this._secondElement.style.left = 0; this._secondElement.style.top = 0; this._secondElement.style.width = "100%"; this._secondElement.style.height = "100%"; this._isShowingOne = true; this.setResizable(false); this.doResize(); }, _removeAllLayoutProperties: function() { this._firstElement.style.removeProperty("right"); this._firstElement.style.removeProperty("bottom"); this._firstElement.style.removeProperty("width"); this._firstElement.style.removeProperty("height"); this._secondElement.style.removeProperty("left"); this._secondElement.style.removeProperty("top"); this._secondElement.style.removeProperty("width"); this._secondElement.style.removeProperty("height"); }, showBoth: function() { this._isShowingOne = false; this._firstElement.removeStyleClass("hidden"); this._firstElement.removeStyleClass("maximized"); this._secondElement.removeStyleClass("hidden"); this._secondElement.removeStyleClass("maximized"); delete this._sidebarSize; this.setSidebarSize(this._lastSidebarSize()); this.setResizable(true); this.doResize(); }, setResizable: function(resizable) { if (this._resizable === resizable) return; this._resizable = resizable; if (resizable) this._resizerElement.removeStyleClass("hidden"); else this._resizerElement.addStyleClass("hidden"); }, setSidebarSize: function(size) { if (this._sidebarSize === size) return; size = this.applyConstraints(size); this._innerSetSidebarSize(size); this._saveSidebarSize(size); }, sidebarSize: function() { return this._sidebarSize; }, totalSize: function() { return this._totalSize; }, _innerSetSidebarSize: function(size) { if (this._isShowingOne) return; this._removeAllLayoutProperties(); if (this._isVertical) { var resizerWidth = this._resizerElement.offsetWidth; if (this._secondIsSidebar) { this._firstElement.style.right = size + "px"; this._secondElement.style.width = size + "px"; this._resizerElement.style.right = size - resizerWidth / 2 + "px"; } else { this._firstElement.style.width = size + "px";; this._secondElement.style.left = size + "px";; this._resizerElement.style.left = size - resizerWidth / 2 + "px"; } } else { var resizerHeight = this._resizerElement.offsetHeight; if (this._secondIsSidebar) { this._firstElement.style.bottom = size + "px";; this._secondElement.style.height = size + "px";; this._resizerElement.style.bottom = size - resizerHeight / 2 + "px"; } else { this._firstElement.style.height = size + "px";; this._secondElement.style.top = size + "px";; this._resizerElement.style.top = size - resizerHeight / 2 + "px"; } } this._sidebarSize = size; this.doResize(); }, applyConstraints: function(size) { const minSize = 20; size = Math.max(size, minSize); if (this._totalSize - size < minSize) size = this._totalSize - minSize; return size; }, wasShown: function() { this._totalSize = this._isVertical ? this.element.offsetWidth : this.element.offsetHeight; this.setSidebarSize(this._lastSidebarSize()); }, onResize: function() { var oldTotalSize = this._totalSize; this._totalSize = this._isVertical ? this.element.offsetWidth : this.element.offsetHeight; }, _startResizerDragging: function(event) { if (!this._resizable) return false; this._dragOffset = (this._secondIsSidebar ? this._totalSize - this._sidebarSize : this._sidebarSize) - (this._isVertical ? event.pageX : event.pageY); return true; }, _resizerDragging: function(event) { var newOffset = (this._isVertical ? event.pageX : event.pageY) + this._dragOffset; var newSize = (this._secondIsSidebar ? this._totalSize - newOffset : newOffset); this.setSidebarSize(newSize); event.preventDefault(); }, _endResizerDragging: function(event) { delete this._dragOffset; }, installResizer: function(resizerElement) { WebInspector.installDragHandle(resizerElement, this._startResizerDragging.bind(this), this._resizerDragging.bind(this), this._endResizerDragging.bind(this), this._isVertical ? "ew-resize" : "ns-resize"); }, _lastSidebarSize: function() { return this._sidebarSizeSettingName ? WebInspector.settings[this._sidebarSizeSettingName].get() || this._savedSidebarSize : this._savedSidebarSize; }, _saveSidebarSize: function(size) { this._savedSidebarSize = size; if (!this._sidebarSizeSettingName) return; WebInspector.settings[this._sidebarSizeSettingName].set(this._savedSidebarSize); }, __proto__: WebInspector.View.prototype } WebInspector.SidebarView = function(sidebarPosition, sidebarWidthSettingName, defaultSidebarWidth) { WebInspector.SplitView.call(this, true, sidebarWidthSettingName, defaultSidebarWidth || 200); this._leftElement = this.firstElement(); this._rightElement = this.secondElement(); this._minimumSidebarWidth = Preferences.minSidebarWidth; this._minimumMainWidthPercent = 50; this._mainElementHidden = false; this._sidebarElementHidden = false; this._innerSetSidebarPosition(sidebarPosition || WebInspector.SidebarView.SidebarPosition.Left); this.setSecondIsSidebar(sidebarPosition !== WebInspector.SidebarView.SidebarPosition.Left); } WebInspector.SidebarView.EventTypes = { Resized: "Resized" } WebInspector.SidebarView.SidebarPosition = { Left: "Left", Right: "Right" } WebInspector.SidebarView.prototype = { _hasLeftSidebar: function() { return this._sidebarPosition === WebInspector.SidebarView.SidebarPosition.Left; }, get mainElement() { return this._hasLeftSidebar() ? this._rightElement : this._leftElement; }, get sidebarElement() { return this._hasLeftSidebar() ? this._leftElement : this._rightElement; }, _innerSetSidebarPosition: function(sidebarPosition) { this._sidebarPosition = sidebarPosition; if (this._hasLeftSidebar()) { this._leftElement.addStyleClass("split-view-sidebar-left"); this._rightElement.removeStyleClass("split-view-sidebar-right"); } else { this._rightElement.addStyleClass("split-view-sidebar-right"); this._leftElement.removeStyleClass("split-view-sidebar-left"); } }, setMinimumSidebarWidth: function(width) { this._minimumSidebarWidth = width; }, setMinimumMainWidthPercent: function(widthPercent) { this._minimumMainWidthPercent = widthPercent; }, setSidebarWidth: function(width) { this.setSidebarSize(width); }, sidebarWidth: function() { return this.sidebarSize(); }, onResize: function() { WebInspector.SplitView.prototype.onResize.call(this); this.dispatchEventToListeners(WebInspector.SidebarView.EventTypes.Resized, this.sidebarWidth()); }, applyConstraints: function(size) { return Number.constrain(size, this._minimumSidebarWidth, this.element.offsetWidth * (100 - this._minimumMainWidthPercent) / 100); }, hideMainElement: function() { if (this._hasLeftSidebar()) this.showOnlyFirst(); else this.showOnlySecond(); }, showMainElement: function() { this.showBoth(); }, hideSidebarElement: function() { if (this._hasLeftSidebar()) this.showOnlySecond(); else this.showOnlyFirst(); }, showSidebarElement: function() { this.showBoth(); }, elementsToRestoreScrollPositionsFor: function() { return [ this.mainElement, this.sidebarElement ]; }, __proto__: WebInspector.SplitView.prototype } WebInspector.ConsolePanel = function() { WebInspector.Panel.call(this, "console"); WebInspector.consoleView.addEventListener(WebInspector.ConsoleView.Events.EntryAdded, this._consoleMessageAdded, this); WebInspector.consoleView.addEventListener(WebInspector.ConsoleView.Events.ConsoleCleared, this._consoleCleared, this); this._view = WebInspector.consoleView; } WebInspector.ConsolePanel.prototype = { get statusBarItems() { return this._view.statusBarItems; }, wasShown: function() { WebInspector.Panel.prototype.wasShown.call(this); if (WebInspector.drawer.visible) { WebInspector.drawer.hide(WebInspector.Drawer.AnimationType.Immediately); this._drawerWasVisible = true; } this._view.show(this.element); }, willHide: function() { if (this._drawerWasVisible) { WebInspector.drawer.show(this._view, WebInspector.Drawer.AnimationType.Immediately); delete this._drawerWasVisible; } WebInspector.Panel.prototype.willHide.call(this); }, searchCanceled: function() { this._clearCurrentSearchResultHighlight(); delete this._searchResults; delete this._searchRegex; }, performSearch: function(query) { WebInspector.searchController.updateSearchMatchesCount(0, this); this.searchCanceled(); this._searchRegex = createPlainTextSearchRegex(query, "gi"); this._searchResults = []; var messages = WebInspector.consoleView.messages; for (var i = 0; i < messages.length; i++) { if (messages[i].matchesRegex(this._searchRegex)) { this._searchResults.push(messages[i]); this._searchRegex.lastIndex = 0; } } WebInspector.searchController.updateSearchMatchesCount(this._searchResults.length, this); this._currentSearchResultIndex = -1; if (this._searchResults.length) this._jumpToSearchResult(0); }, jumpToNextSearchResult: function() { if (!this._searchResults || !this._searchResults.length) return; this._jumpToSearchResult((this._currentSearchResultIndex + 1) % this._searchResults.length); }, jumpToPreviousSearchResult: function() { if (!this._searchResults || !this._searchResults.length) return; var index = this._currentSearchResultIndex - 1; if (index === -1) index = this._searchResults.length - 1; this._jumpToSearchResult(index); return true; }, _clearCurrentSearchResultHighlight: function() { if (!this._searchResults) return; var highlightedMessage = this._searchResults[this._currentSearchResultIndex]; if (highlightedMessage) highlightedMessage.clearHighlight(); this._currentSearchResultIndex = -1; }, _jumpToSearchResult: function(index) { this._clearCurrentSearchResultHighlight(); this._currentSearchResultIndex = index; WebInspector.searchController.updateCurrentMatchIndex(this._currentSearchResultIndex, this); this._searchResults[index].highlightSearchResults(this._searchRegex); }, _consoleMessageAdded: function(event) { if (!this._searchRegex || !this.isShowing()) return; var message = event.data; this._searchRegex.lastIndex = 0; if (message.matchesRegex(this._searchRegex)) { this._searchResults.push(message); WebInspector.searchController.updateSearchMatchesCount(this._searchResults.length, this); } }, _consoleCleared: function() { if (!this._searchResults) return; this._clearCurrentSearchResultHighlight(); this._searchResults.length = 0; if (this.isShowing()) WebInspector.searchController.updateSearchMatchesCount(0, this); }, __proto__: WebInspector.Panel.prototype } function defineCommonExtensionSymbols(apiPrivate) { if (!apiPrivate.audits) apiPrivate.audits = {}; apiPrivate.audits.Severity = { Info: "info", Warning: "warning", Severe: "severe" }; if (!apiPrivate.console) apiPrivate.console = {}; apiPrivate.console.Severity = { Tip: "tip", Debug: "debug", Log: "log", Warning: "warning", Error: "error" }; if (!apiPrivate.panels) apiPrivate.panels = {}; apiPrivate.panels.SearchAction = { CancelSearch: "cancelSearch", PerformSearch: "performSearch", NextSearchResult: "nextSearchResult", PreviousSearchResult: "previousSearchResult" }; apiPrivate.Events = { AuditStarted: "audit-started-", ButtonClicked: "button-clicked-", ConsoleMessageAdded: "console-message-added", ElementsPanelObjectSelected: "panel-objectSelected-elements", NetworkRequestFinished: "network-request-finished", Reset: "reset", OpenResource: "open-resource", PanelSearch: "panel-search-", Reload: "Reload", ResourceAdded: "resource-added", ResourceContentCommitted: "resource-content-committed", TimelineEventRecorded: "timeline-event-recorded", ViewShown: "view-shown-", ViewHidden: "view-hidden-" }; apiPrivate.Commands = { AddAuditCategory: "addAuditCategory", AddAuditResult: "addAuditResult", AddConsoleMessage: "addConsoleMessage", AddRequestHeaders: "addRequestHeaders", CreatePanel: "createPanel", CreateSidebarPane: "createSidebarPane", CreateStatusBarButton: "createStatusBarButton", EvaluateOnInspectedPage: "evaluateOnInspectedPage", GetConsoleMessages: "getConsoleMessages", GetHAR: "getHAR", GetPageResources: "getPageResources", GetRequestContent: "getRequestContent", GetResourceContent: "getResourceContent", Subscribe: "subscribe", SetOpenResourceHandler: "setOpenResourceHandler", SetResourceContent: "setResourceContent", SetSidebarContent: "setSidebarContent", SetSidebarHeight: "setSidebarHeight", SetSidebarPage: "setSidebarPage", ShowPanel: "showPanel", StopAuditCategoryRun: "stopAuditCategoryRun", Unsubscribe: "unsubscribe", UpdateAuditProgress: "updateAuditProgress", UpdateButton: "updateButton", InspectedURLChanged: "inspectedURLChanged" }; } function injectedExtensionAPI(injectedScriptId) { var apiPrivate = {}; defineCommonExtensionSymbols(apiPrivate); var commands = apiPrivate.Commands; var events = apiPrivate.Events; var userAction = false; function EventSinkImpl(type, customDispatch) { this._type = type; this._listeners = []; this._customDispatch = customDispatch; } EventSinkImpl.prototype = { addListener: function(callback) { if (typeof callback !== "function") throw "addListener: callback is not a function"; if (this._listeners.length === 0) extensionServer.sendRequest({ command: commands.Subscribe, type: this._type }); this._listeners.push(callback); extensionServer.registerHandler("notify-" + this._type, this._dispatch.bind(this)); }, removeListener: function(callback) { var listeners = this._listeners; for (var i = 0; i < listeners.length; ++i) { if (listeners[i] === callback) { listeners.splice(i, 1); break; } } if (this._listeners.length === 0) extensionServer.sendRequest({ command: commands.Unsubscribe, type: this._type }); }, _fire: function() { var listeners = this._listeners.slice(); for (var i = 0; i < listeners.length; ++i) listeners[i].apply(null, arguments); }, _dispatch: function(request) { if (this._customDispatch) this._customDispatch.call(this, request); else this._fire.apply(this, request.arguments); } } function InspectorExtensionAPI() { this.audits = new Audits(); this.inspectedWindow = new InspectedWindow(); this.panels = new Panels(); this.network = new Network(); defineDeprecatedProperty(this, "webInspector", "resources", "network"); this.timeline = new Timeline(); this.console = new ConsoleAPI(); this.onReset = new EventSink(events.Reset); } InspectorExtensionAPI.prototype = { log: function(message) { extensionServer.sendRequest({ command: commands.Log, message: message }); } } function ConsoleAPI() { this.onMessageAdded = new EventSink(events.ConsoleMessageAdded); } ConsoleAPI.prototype = { getMessages: function(callback) { extensionServer.sendRequest({ command: commands.GetConsoleMessages }, callback); }, addMessage: function(severity, text, url, line) { extensionServer.sendRequest({ command: commands.AddConsoleMessage, severity: severity, text: text, url: url, line: line }); }, get Severity() { return apiPrivate.console.Severity; } } function Network() { function dispatchRequestEvent(message) { var request = message.arguments[1]; request.__proto__ = new Request(message.arguments[0]); this._fire(request); } this.onRequestFinished = new EventSink(events.NetworkRequestFinished, dispatchRequestEvent); defineDeprecatedProperty(this, "network", "onFinished", "onRequestFinished"); this.onNavigated = new EventSink(events.InspectedURLChanged); } Network.prototype = { getHAR: function(callback) { function callbackWrapper(result) { var entries = (result && result.entries) || []; for (var i = 0; i < entries.length; ++i) { entries[i].__proto__ = new Request(entries[i]._requestId); delete entries[i]._requestId; } callback(result); } return extensionServer.sendRequest({ command: commands.GetHAR }, callback && callbackWrapper); }, addRequestHeaders: function(headers) { return extensionServer.sendRequest({ command: commands.AddRequestHeaders, headers: headers, extensionId: window.location.hostname }); } } function RequestImpl(id) { this._id = id; } RequestImpl.prototype = { getContent: function(callback) { function callbackWrapper(response) { callback(response.content, response.encoding); } extensionServer.sendRequest({ command: commands.GetRequestContent, id: this._id }, callback && callbackWrapper); } } function Panels() { var panels = { elements: new ElementsPanel() }; function panelGetter(name) { return panels[name]; } for (var panel in panels) this.__defineGetter__(panel, panelGetter.bind(null, panel)); } Panels.prototype = { create: function(title, icon, page, callback) { var id = "extension-panel-" + extensionServer.nextObjectId(); var request = { command: commands.CreatePanel, id: id, title: title, icon: icon, page: page }; extensionServer.sendRequest(request, callback && callback.bind(this, new ExtensionPanel(id))); }, setOpenResourceHandler: function(callback) { var hadHandler = extensionServer.hasHandler(events.OpenResource); if (!callback) extensionServer.unregisterHandler(events.OpenResource); else { function callbackWrapper(message) { userAction = true; try { callback.call(null, new Resource(message.resource), message.lineNumber); } finally { userAction = false; } } extensionServer.registerHandler(events.OpenResource, callbackWrapper); } if (hadHandler === !callback) extensionServer.sendRequest({ command: commands.SetOpenResourceHandler, "handlerPresent": !!callback }); }, get SearchAction() { return apiPrivate.panels.SearchAction; } } function ExtensionViewImpl(id) { this._id = id; function dispatchShowEvent(message) { var frameIndex = message.arguments[0]; this._fire(window.parent.frames[frameIndex]); } this.onShown = new EventSink(events.ViewShown + id, dispatchShowEvent); this.onHidden = new EventSink(events.ViewHidden + id); } function PanelWithSidebarImpl(id) { this._id = id; } PanelWithSidebarImpl.prototype = { createSidebarPane: function(title, callback) { var id = "extension-sidebar-" + extensionServer.nextObjectId(); var request = { command: commands.CreateSidebarPane, panel: this._id, id: id, title: title }; function callbackWrapper() { callback(new ExtensionSidebarPane(id)); } extensionServer.sendRequest(request, callback && callbackWrapper); }, __proto__: ExtensionViewImpl.prototype } function ElementsPanel() { var id = "elements"; PanelWithSidebar.call(this, id); this.onSelectionChanged = new EventSink(events.ElementsPanelObjectSelected); } function ExtensionPanelImpl(id) { ExtensionViewImpl.call(this, id); this.onSearch = new EventSink(events.PanelSearch + id); } ExtensionPanelImpl.prototype = { createStatusBarButton: function(iconPath, tooltipText, disabled) { var id = "button-" + extensionServer.nextObjectId(); var request = { command: commands.CreateStatusBarButton, panel: this._id, id: id, icon: iconPath, tooltip: tooltipText, disabled: !!disabled }; extensionServer.sendRequest(request); return new Button(id); }, show: function() { if (!userAction) return; var request = { command: commands.ShowPanel, id: this._id }; extensionServer.sendRequest(request); }, __proto__: ExtensionViewImpl.prototype } function ExtensionSidebarPaneImpl(id) { ExtensionViewImpl.call(this, id); } ExtensionSidebarPaneImpl.prototype = { setHeight: function(height) { extensionServer.sendRequest({ command: commands.SetSidebarHeight, id: this._id, height: height }); }, setExpression: function(expression, rootTitle, evaluateOptions) { var callback = extractCallbackArgument(arguments); var request = { command: commands.SetSidebarContent, id: this._id, expression: expression, rootTitle: rootTitle, evaluateOnPage: true, }; if (typeof evaluateOptions === "object") request.evaluateOptions = evaluateOptions; extensionServer.sendRequest(request, callback); }, setObject: function(jsonObject, rootTitle, callback) { extensionServer.sendRequest({ command: commands.SetSidebarContent, id: this._id, expression: jsonObject, rootTitle: rootTitle }, callback); }, setPage: function(page) { extensionServer.sendRequest({ command: commands.SetSidebarPage, id: this._id, page: page }); } } function ButtonImpl(id) { this._id = id; this.onClicked = new EventSink(events.ButtonClicked + id); } ButtonImpl.prototype = { update: function(iconPath, tooltipText, disabled) { var request = { command: commands.UpdateButton, id: this._id, icon: iconPath, tooltip: tooltipText, disabled: !!disabled }; extensionServer.sendRequest(request); } }; function Audits() { } Audits.prototype = { addCategory: function(displayName, resultCount) { var id = "extension-audit-category-" + extensionServer.nextObjectId(); if (typeof resultCount !== "undefined") console.warn("Passing resultCount to audits.addCategory() is deprecated. Use AuditResult.updateProgress() instead."); extensionServer.sendRequest({ command: commands.AddAuditCategory, id: id, displayName: displayName, resultCount: resultCount }); return new AuditCategory(id); } } function AuditCategoryImpl(id) { function dispatchAuditEvent(request) { var auditResult = new AuditResult(request.arguments[0]); try { this._fire(auditResult); } catch (e) { console.error("Uncaught exception in extension audit event handler: " + e); auditResult.done(); } } this._id = id; this.onAuditStarted = new EventSink(events.AuditStarted + id, dispatchAuditEvent); } function AuditResultImpl(id) { this._id = id; this.createURL = this._nodeFactory.bind(null, "url"); this.createSnippet = this._nodeFactory.bind(null, "snippet"); this.createText = this._nodeFactory.bind(null, "text"); this.createObject = this._nodeFactory.bind(null, "object"); this.createNode = this._nodeFactory.bind(null, "node"); } AuditResultImpl.prototype = { addResult: function(displayName, description, severity, details) { if (details && !(details instanceof AuditResultNode)) details = new AuditResultNode(details instanceof Array ? details : [details]); var request = { command: commands.AddAuditResult, resultId: this._id, displayName: displayName, description: description, severity: severity, details: details }; extensionServer.sendRequest(request); }, createResult: function() { return new AuditResultNode(Array.prototype.slice.call(arguments)); }, updateProgress: function(worked, totalWork) { extensionServer.sendRequest({ command: commands.UpdateAuditProgress, resultId: this._id, progress: worked / totalWork }); }, done: function() { extensionServer.sendRequest({ command: commands.StopAuditCategoryRun, resultId: this._id }); }, get Severity() { return apiPrivate.audits.Severity; }, createResourceLink: function(url, lineNumber) { return { type: "resourceLink", arguments: [url, lineNumber && lineNumber - 1] }; }, _nodeFactory: function(type) { return { type: type, arguments: Array.prototype.slice.call(arguments, 1) }; } } function AuditResultNode(contents) { this.contents = contents; this.children = []; this.expanded = false; } AuditResultNode.prototype = { addChild: function() { var node = new AuditResultNode(Array.prototype.slice.call(arguments)); this.children.push(node); return node; } }; function InspectedWindow() { function dispatchResourceEvent(message) { this._fire(new Resource(message.arguments[0])); } function dispatchResourceContentEvent(message) { this._fire(new Resource(message.arguments[0]), message.arguments[1]); } this.onResourceAdded = new EventSink(events.ResourceAdded, dispatchResourceEvent); this.onResourceContentCommitted = new EventSink(events.ResourceContentCommitted, dispatchResourceContentEvent); } InspectedWindow.prototype = { reload: function(optionsOrUserAgent) { var options = null; if (typeof optionsOrUserAgent === "object") options = optionsOrUserAgent; else if (typeof optionsOrUserAgent === "string") { options = { userAgent: optionsOrUserAgent }; console.warn("Passing userAgent as string parameter to inspectedWindow.reload() is deprecated. " + "Use inspectedWindow.reload({ userAgent: value}) instead."); } return extensionServer.sendRequest({ command: commands.Reload, options: options }); }, eval: function(expression, evaluateOptions) { var callback = extractCallbackArgument(arguments); function callbackWrapper(result) { callback(result.value, result.isException); } var request = { command: commands.EvaluateOnInspectedPage, expression: expression }; if (typeof evaluateOptions === "object") request.evaluateOptions = evaluateOptions; return extensionServer.sendRequest(request, callback && callbackWrapper); }, getResources: function(callback) { function wrapResource(resourceData) { return new Resource(resourceData); } function callbackWrapper(resources) { callback(resources.map(wrapResource)); } return extensionServer.sendRequest({ command: commands.GetPageResources }, callback && callbackWrapper); } } function ResourceImpl(resourceData) { this._url = resourceData.url this._type = resourceData.type; } ResourceImpl.prototype = { get url() { return this._url; }, get type() { return this._type; }, getContent: function(callback) { function callbackWrapper(response) { callback(response.content, response.encoding); } return extensionServer.sendRequest({ command: commands.GetResourceContent, url: this._url }, callback && callbackWrapper); }, setContent: function(content, commit, callback) { return extensionServer.sendRequest({ command: commands.SetResourceContent, url: this._url, content: content, commit: commit }, callback); } } function TimelineImpl() { this.onEventRecorded = new EventSink(events.TimelineEventRecorded); } function ExtensionServerClient() { this._callbacks = {}; this._handlers = {}; this._lastRequestId = 0; this._lastObjectId = 0; this.registerHandler("callback", this._onCallback.bind(this)); var channel = new MessageChannel(); this._port = channel.port1; this._port.addEventListener("message", this._onMessage.bind(this), false); this._port.start(); window.parent.postMessage("registerExtension", [ channel.port2 ], "*"); } ExtensionServerClient.prototype = { sendRequest: function(message, callback) { if (typeof callback === "function") message.requestId = this._registerCallback(callback); return this._port.postMessage(message); }, hasHandler: function(command) { return !!this._handlers[command]; }, registerHandler: function(command, handler) { this._handlers[command] = handler; }, unregisterHandler: function(command) { delete this._handlers[command]; }, nextObjectId: function() { return injectedScriptId + "_" + ++this._lastObjectId; }, _registerCallback: function(callback) { var id = ++this._lastRequestId; this._callbacks[id] = callback; return id; }, _onCallback: function(request) { if (request.requestId in this._callbacks) { var callback = this._callbacks[request.requestId]; delete this._callbacks[request.requestId]; callback(request.result); } }, _onMessage: function(event) { var request = event.data; var handler = this._handlers[request.command]; if (handler) handler.call(this, request); } } function populateInterfaceClass(interface, implementation) { for (var member in implementation) { if (member.charAt(0) === "_") continue; var descriptor = null; for (var owner = implementation; owner && !descriptor; owner = owner.__proto__) descriptor = Object.getOwnPropertyDescriptor(owner, member); if (!descriptor) continue; if (typeof descriptor.value === "function") interface[member] = descriptor.value.bind(implementation); else if (typeof descriptor.get === "function") interface.__defineGetter__(member, descriptor.get.bind(implementation)); else Object.defineProperty(interface, member, descriptor); } } function declareInterfaceClass(implConstructor) { return function() { var impl = { __proto__: implConstructor.prototype }; implConstructor.apply(impl, arguments); populateInterfaceClass(this, impl); } } function defineDeprecatedProperty(object, className, oldName, newName) { var warningGiven = false; function getter() { if (!warningGiven) { console.warn(className + "." + oldName + " is deprecated. Use " + className + "." + newName + " instead"); warningGiven = true; } return object[newName]; } object.__defineGetter__(oldName, getter); } function extractCallbackArgument(args) { var lastArgument = args[args.length - 1]; return typeof lastArgument === "function" ? lastArgument : undefined; } var AuditCategory = declareInterfaceClass(AuditCategoryImpl); var AuditResult = declareInterfaceClass(AuditResultImpl); var Button = declareInterfaceClass(ButtonImpl); var EventSink = declareInterfaceClass(EventSinkImpl); var ExtensionPanel = declareInterfaceClass(ExtensionPanelImpl); var ExtensionSidebarPane = declareInterfaceClass(ExtensionSidebarPaneImpl); var PanelWithSidebar = declareInterfaceClass(PanelWithSidebarImpl); var Request = declareInterfaceClass(RequestImpl); var Resource = declareInterfaceClass(ResourceImpl); var Timeline = declareInterfaceClass(TimelineImpl); var extensionServer = new ExtensionServerClient(); return new InspectorExtensionAPI(); } function buildPlatformExtensionAPI(extensionInfo) { function platformExtensionAPI(coreAPI) { window.webInspector = coreAPI; } return platformExtensionAPI.toString(); } function buildExtensionAPIInjectedScript(extensionInfo) { return "(function(injectedScriptHost, inspectedWindow, injectedScriptId){ " + defineCommonExtensionSymbols.toString() + ";" + injectedExtensionAPI.toString() + ";" + buildPlatformExtensionAPI(extensionInfo) + ";" + "platformExtensionAPI(injectedExtensionAPI(injectedScriptId));" + "return {};" + "})"; } WebInspector.ExtensionAuditCategory = function(extensionOrigin, id, displayName, ruleCount) { this._extensionOrigin = extensionOrigin; this._id = id; this._displayName = displayName; this._ruleCount = ruleCount; } WebInspector.ExtensionAuditCategory.prototype = { get id() { return this._id; }, get displayName() { return this._displayName; }, run: function(requests, ruleResultCallback, categoryDoneCallback, progress) { var results = new WebInspector.ExtensionAuditCategoryResults(this, ruleResultCallback, categoryDoneCallback, progress); WebInspector.extensionServer.startAuditRun(this, results); } } WebInspector.ExtensionAuditCategoryResults = function(category, ruleResultCallback, categoryDoneCallback, progress) { this._category = category; this._ruleResultCallback = ruleResultCallback; this._categoryDoneCallback = categoryDoneCallback; this._progress = progress; this._progress.setTotalWork(1); this._expectedResults = category._ruleCount; this._actualResults = 0; this.id = category.id + "-" + ++WebInspector.ExtensionAuditCategoryResults._lastId; } WebInspector.ExtensionAuditCategoryResults.prototype = { done: function() { WebInspector.extensionServer.stopAuditRun(this); this._progress.done(); this._categoryDoneCallback(); }, addResult: function(displayName, description, severity, details) { var result = new WebInspector.AuditRuleResult(displayName); result.addChild(description); result.severity = severity; if (details) this._addNode(result, details); this._addResult(result); }, _addNode: function(parent, node) { var contents = WebInspector.auditFormatters.partiallyApply(WebInspector.ExtensionAuditFormatters, this, node.contents); var addedNode = parent.addChild(contents, node.expanded); if (node.children) { for (var i = 0; i < node.children.length; ++i) this._addNode(addedNode, node.children[i]); } }, _addResult: function(result) { this._ruleResultCallback(result); ++this._actualResults; if (typeof this._expectedResults === "number") { this._progress.setWorked(this._actualResults / this._expectedResults); if (this._actualResults === this._expectedResults) this.done(); } }, updateProgress: function(progress) { this._progress.setWorked(progress); }, evaluate: function(expression, evaluateOptions, callback) { function onEvaluate(error, result, wasThrown) { if (wasThrown) return; var object = WebInspector.RemoteObject.fromPayload(result); callback(object); } WebInspector.extensionServer.evaluate(expression, false, false, evaluateOptions, this._category._extensionOrigin, onEvaluate); } } WebInspector.ExtensionAuditFormatters = { object: function(expression, title, evaluateOptions) { var parentElement = document.createElement("div"); function onEvaluate(remoteObject) { var section = new WebInspector.ObjectPropertiesSection(remoteObject, title); section.expanded = true; section.editable = false; parentElement.appendChild(section.element); } this.evaluate(expression, evaluateOptions, onEvaluate); return parentElement; }, node: function(expression, evaluateOptions) { var parentElement = document.createElement("div"); function onNodeAvailable(nodeId) { if (!nodeId) return; var treeOutline = new WebInspector.ElementsTreeOutline(false, false, true); treeOutline.rootDOMNode = WebInspector.domAgent.nodeForId(nodeId); treeOutline.element.addStyleClass("outline-disclosure"); treeOutline.setVisible(true); parentElement.appendChild(treeOutline.element); } function onEvaluate(remoteObject) { remoteObject.pushNodeToFrontend(onNodeAvailable); } this.evaluate(expression, evaluateOptions, onEvaluate); return parentElement; } } WebInspector.ExtensionAuditCategoryResults._lastId = 0; WebInspector.ExtensionServer = function() { this._clientObjects = {}; this._handlers = {}; this._subscribers = {}; this._subscriptionStartHandlers = {}; this._subscriptionStopHandlers = {}; this._extraHeaders = {}; this._requests = {}; this._lastRequestId = 0; this._registeredExtensions = {}; this._status = new WebInspector.ExtensionStatus(); var commands = WebInspector.extensionAPI.Commands; this._registerHandler(commands.AddAuditCategory, this._onAddAuditCategory.bind(this)); this._registerHandler(commands.AddAuditResult, this._onAddAuditResult.bind(this)); this._registerHandler(commands.AddConsoleMessage, this._onAddConsoleMessage.bind(this)); this._registerHandler(commands.AddRequestHeaders, this._onAddRequestHeaders.bind(this)); this._registerHandler(commands.CreatePanel, this._onCreatePanel.bind(this)); this._registerHandler(commands.CreateSidebarPane, this._onCreateSidebarPane.bind(this)); this._registerHandler(commands.CreateStatusBarButton, this._onCreateStatusBarButton.bind(this)); this._registerHandler(commands.EvaluateOnInspectedPage, this._onEvaluateOnInspectedPage.bind(this)); this._registerHandler(commands.GetHAR, this._onGetHAR.bind(this)); this._registerHandler(commands.GetConsoleMessages, this._onGetConsoleMessages.bind(this)); this._registerHandler(commands.GetPageResources, this._onGetPageResources.bind(this)); this._registerHandler(commands.GetRequestContent, this._onGetRequestContent.bind(this)); this._registerHandler(commands.GetResourceContent, this._onGetResourceContent.bind(this)); this._registerHandler(commands.Log, this._onLog.bind(this)); this._registerHandler(commands.Reload, this._onReload.bind(this)); this._registerHandler(commands.SetOpenResourceHandler, this._onSetOpenResourceHandler.bind(this)); this._registerHandler(commands.SetResourceContent, this._onSetResourceContent.bind(this)); this._registerHandler(commands.SetSidebarHeight, this._onSetSidebarHeight.bind(this)); this._registerHandler(commands.SetSidebarContent, this._onSetSidebarContent.bind(this)); this._registerHandler(commands.SetSidebarPage, this._onSetSidebarPage.bind(this)); this._registerHandler(commands.ShowPanel, this._onShowPanel.bind(this)); this._registerHandler(commands.StopAuditCategoryRun, this._onStopAuditCategoryRun.bind(this)); this._registerHandler(commands.Subscribe, this._onSubscribe.bind(this)); this._registerHandler(commands.Unsubscribe, this._onUnsubscribe.bind(this)); this._registerHandler(commands.UpdateButton, this._onUpdateButton.bind(this)); this._registerHandler(commands.UpdateAuditProgress, this._onUpdateAuditProgress.bind(this)); window.addEventListener("message", this._onWindowMessage.bind(this), false); } WebInspector.ExtensionServer.prototype = { hasExtensions: function() { return !!Object.keys(this._registeredExtensions).length; }, notifySearchAction: function(panelId, action, searchString) { this._postNotification(WebInspector.extensionAPI.Events.PanelSearch + panelId, action, searchString); }, notifyViewShown: function(identifier, frameIndex) { this._postNotification(WebInspector.extensionAPI.Events.ViewShown + identifier, frameIndex); }, notifyViewHidden: function(identifier) { this._postNotification(WebInspector.extensionAPI.Events.ViewHidden + identifier); }, notifyButtonClicked: function(identifier) { this._postNotification(WebInspector.extensionAPI.Events.ButtonClicked + identifier); }, _inspectedURLChanged: function(event) { this._requests = {}; var url = event.data; this._postNotification(WebInspector.extensionAPI.Events.InspectedURLChanged, url); }, _mainFrameNavigated: function(event) { this._postNotification(WebInspector.extensionAPI.Events.Reset); }, startAuditRun: function(category, auditRun) { this._clientObjects[auditRun.id] = auditRun; this._postNotification("audit-started-" + category.id, auditRun.id); }, stopAuditRun: function(auditRun) { delete this._clientObjects[auditRun.id]; }, _postNotification: function(type, vararg) { var subscribers = this._subscribers[type]; if (!subscribers) return; var message = { command: "notify-" + type, arguments: Array.prototype.slice.call(arguments, 1) }; for (var i = 0; i < subscribers.length; ++i) subscribers[i].postMessage(message); }, _onSubscribe: function(message, port) { var subscribers = this._subscribers[message.type]; if (subscribers) subscribers.push(port); else { this._subscribers[message.type] = [ port ]; if (this._subscriptionStartHandlers[message.type]) this._subscriptionStartHandlers[message.type](); } }, _onUnsubscribe: function(message, port) { var subscribers = this._subscribers[message.type]; if (!subscribers) return; subscribers.remove(port); if (!subscribers.length) { delete this._subscribers[message.type]; if (this._subscriptionStopHandlers[message.type]) this._subscriptionStopHandlers[message.type](); } }, _onAddRequestHeaders: function(message) { var id = message.extensionId; if (typeof id !== "string") return this._status.E_BADARGTYPE("extensionId", typeof id, "string"); var extensionHeaders = this._extraHeaders[id]; if (!extensionHeaders) { extensionHeaders = {}; this._extraHeaders[id] = extensionHeaders; } for (var name in message.headers) extensionHeaders[name] = message.headers[name]; var allHeaders = ({}); for (var extension in this._extraHeaders) { var headers = this._extraHeaders[extension]; for (name in headers) { if (typeof headers[name] === "string") allHeaders[name] = headers[name]; } } NetworkAgent.setExtraHTTPHeaders(allHeaders); }, _onCreatePanel: function(message, port) { var id = message.id; if (id in this._clientObjects || id in WebInspector.panels) return this._status.E_EXISTS(id); var page = this._expandResourcePath(port._extensionOrigin, message.page); var panelDescriptor = new WebInspector.PanelDescriptor(id, message.title, undefined, undefined, new WebInspector.ExtensionPanel(id, page)); panelDescriptor.setIconURL(this._expandResourcePath(port._extensionOrigin, message.icon)); this._clientObjects[id] = panelDescriptor.panel(); WebInspector.inspectorView.addPanel(panelDescriptor); return this._status.OK(); }, _onShowPanel: function(message) { WebInspector.showPanel(message.id); }, _onCreateStatusBarButton: function(message, port) { var panel = this._clientObjects[message.panel]; if (!panel || !(panel instanceof WebInspector.ExtensionPanel)) return this._status.E_NOTFOUND(message.panel); var button = new WebInspector.ExtensionButton(message.id, this._expandResourcePath(port._extensionOrigin, message.icon), message.tooltip, message.disabled); this._clientObjects[message.id] = button; panel.addStatusBarItem(button.element); return this._status.OK(); }, _onUpdateButton: function(message, port) { var button = this._clientObjects[message.id]; if (!button || !(button instanceof WebInspector.ExtensionButton)) return this._status.E_NOTFOUND(message.id); button.update(this._expandResourcePath(port._extensionOrigin, message.icon), message.tooltip, message.disabled); return this._status.OK(); }, _onCreateSidebarPane: function(message) { var panel = WebInspector.panel(message.panel); if (!panel) return this._status.E_NOTFOUND(message.panel); if (!panel.sidebarElement || !panel.sidebarPanes) return this._status.E_NOTSUPPORTED(); var id = message.id; var sidebar = new WebInspector.ExtensionSidebarPane(message.title, message.id); this._clientObjects[id] = sidebar; panel.sidebarPanes[id] = sidebar; panel.sidebarElement.appendChild(sidebar.element); return this._status.OK(); }, _onSetSidebarHeight: function(message) { var sidebar = this._clientObjects[message.id]; if (!sidebar) return this._status.E_NOTFOUND(message.id); sidebar.setHeight(message.height); return this._status.OK(); }, _onSetSidebarContent: function(message, port) { var sidebar = this._clientObjects[message.id]; if (!sidebar) return this._status.E_NOTFOUND(message.id); function callback(error) { var result = error ? this._status.E_FAILED(error) : this._status.OK(); this._dispatchCallback(message.requestId, port, result); } if (message.evaluateOnPage) return sidebar.setExpression(message.expression, message.rootTitle, message.evaluateOptions, port._extensionOrigin, callback.bind(this)); sidebar.setObject(message.expression, message.rootTitle, callback.bind(this)); }, _onSetSidebarPage: function(message, port) { var sidebar = this._clientObjects[message.id]; if (!sidebar) return this._status.E_NOTFOUND(message.id); sidebar.setPage(this._expandResourcePath(port._extensionOrigin, message.page)); }, _onSetOpenResourceHandler: function(message, port) { var name = this._registeredExtensions[port._extensionOrigin].name || ("Extension " + port._extensionOrigin); if (message.handlerPresent) WebInspector.openAnchorLocationRegistry.registerHandler(name, this._handleOpenURL.bind(this, port)); else WebInspector.openAnchorLocationRegistry.unregisterHandler(name); }, _handleOpenURL: function(port, details) { var url = (details.url); var contentProvider = WebInspector.workspace.uiSourceCodeForURL(url) || WebInspector.resourceForURL(url); if (!contentProvider) return false; var lineNumber = details.lineNumber; if (typeof lineNumber === "number") lineNumber += 1; port.postMessage({ command: "open-resource", resource: this._makeResource(contentProvider), lineNumber: lineNumber }); return true; }, _onLog: function(message) { WebInspector.log(message.message); }, _onReload: function(message) { var options = (message.options || {}); NetworkAgent.setUserAgentOverride(typeof options.userAgent === "string" ? options.userAgent : ""); var injectedScript; if (options.injectedScript) { injectedScript = "((function(){" + options.injectedScript + "})(),function(){return {}})"; } PageAgent.reload(!!options.ignoreCache, injectedScript); return this._status.OK(); }, _onEvaluateOnInspectedPage: function(message, port) { function callback(error, resultPayload, wasThrown) { var result = {}; if (error) { result.isException = true; result.value = error.toString(); } else result.value = resultPayload.value; if (wasThrown) result.isException = true; this._dispatchCallback(message.requestId, port, result); } return this.evaluate(message.expression, true, true, message.evaluateOptions, port._extensionOrigin, callback.bind(this)); }, _onGetConsoleMessages: function() { return WebInspector.console.messages.map(this._makeConsoleMessage); }, _onAddConsoleMessage: function(message) { function convertSeverity(level) { switch (level) { case WebInspector.extensionAPI.console.Severity.Tip: return WebInspector.ConsoleMessage.MessageLevel.Tip; case WebInspector.extensionAPI.console.Severity.Log: return WebInspector.ConsoleMessage.MessageLevel.Log; case WebInspector.extensionAPI.console.Severity.Warning: return WebInspector.ConsoleMessage.MessageLevel.Warning; case WebInspector.extensionAPI.console.Severity.Error: return WebInspector.ConsoleMessage.MessageLevel.Error; case WebInspector.extensionAPI.console.Severity.Debug: return WebInspector.ConsoleMessage.MessageLevel.Debug; } } var level = convertSeverity(message.severity); if (!level) return this._status.E_BADARG("message.severity", message.severity); var consoleMessage = WebInspector.ConsoleMessage.create( WebInspector.ConsoleMessage.MessageSource.JS, level, message.text, WebInspector.ConsoleMessage.MessageType.Log, message.url, message.line); WebInspector.console.addMessage(consoleMessage); }, _makeConsoleMessage: function(message) { function convertLevel(level) { if (!level) return; switch (level) { case WebInspector.ConsoleMessage.MessageLevel.Tip: return WebInspector.extensionAPI.console.Severity.Tip; case WebInspector.ConsoleMessage.MessageLevel.Log: return WebInspector.extensionAPI.console.Severity.Log; case WebInspector.ConsoleMessage.MessageLevel.Warning: return WebInspector.extensionAPI.console.Severity.Warning; case WebInspector.ConsoleMessage.MessageLevel.Error: return WebInspector.extensionAPI.console.Severity.Error; case WebInspector.ConsoleMessage.MessageLevel.Debug: return WebInspector.extensionAPI.console.Severity.Debug; default: return WebInspector.extensionAPI.console.Severity.Log; } } var result = { severity: convertLevel(message.level), text: message.text, }; if (message.url) result.url = message.url; if (message.line) result.line = message.line; return result; }, _onGetHAR: function() { var requests = WebInspector.networkLog.requests; var harLog = (new WebInspector.HARLog(requests)).build(); for (var i = 0; i < harLog.entries.length; ++i) harLog.entries[i]._requestId = this._requestId(requests[i]); return harLog; }, _makeResource: function(contentProvider) { return { url: contentProvider.contentURL(), type: contentProvider.contentType().name() }; }, _onGetPageResources: function() { var resources = {}; function pushResourceData(contentProvider) { if (!resources[contentProvider.contentURL()]) resources[contentProvider.contentURL()] = this._makeResource(contentProvider); } WebInspector.workspace.uiSourceCodes().forEach(pushResourceData.bind(this)); WebInspector.resourceTreeModel.forAllResources(pushResourceData.bind(this)); return Object.values(resources); }, _getResourceContent: function(contentProvider, message, port) { function onContentAvailable(content, contentEncoded, mimeType) { var response = { encoding: contentEncoded ? "base64" : "", content: content }; this._dispatchCallback(message.requestId, port, response); } contentProvider.requestContent(onContentAvailable.bind(this)); }, _onGetRequestContent: function(message, port) { var request = this._requestById(message.id); if (!request) return this._status.E_NOTFOUND(message.id); this._getResourceContent(request, message, port); }, _onGetResourceContent: function(message, port) { var url = (message.url); var contentProvider = WebInspector.workspace.uiSourceCodeForURL(url) || WebInspector.resourceForURL(url); if (!contentProvider) return this._status.E_NOTFOUND(url); this._getResourceContent(contentProvider, message, port); }, _onSetResourceContent: function(message, port) { function callbackWrapper(error) { var response = error ? this._status.E_FAILED(error) : this._status.OK(); this._dispatchCallback(message.requestId, port, response); } var url = (message.url); var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(url); if (!uiSourceCode) { var resource = WebInspector.resourceTreeModel.resourceForURL(url); if (!resource) return this._status.E_NOTFOUND(url); return this._status.E_NOTSUPPORTED("Resource is not editable") } uiSourceCode.setWorkingCopy(message.content); if (message.commit) uiSourceCode.commitWorkingCopy(callbackWrapper.bind(this)); else callbackWrapper.call(this, null); }, _requestId: function(request) { if (!request._extensionRequestId) { request._extensionRequestId = ++this._lastRequestId; this._requests[request._extensionRequestId] = request; } return request._extensionRequestId; }, _requestById: function(id) { return this._requests[id]; }, _onAddAuditCategory: function(message, port) { var category = new WebInspector.ExtensionAuditCategory(port._extensionOrigin, message.id, message.displayName, message.resultCount); if (WebInspector.panel("audits").getCategory(category.id)) return this._status.E_EXISTS(category.id); this._clientObjects[message.id] = category; WebInspector.panel("audits").addCategory(category); }, _onAddAuditResult: function(message) { var auditResult = this._clientObjects[message.resultId]; if (!auditResult) return this._status.E_NOTFOUND(message.resultId); try { auditResult.addResult(message.displayName, message.description, message.severity, message.details); } catch (e) { return e; } return this._status.OK(); }, _onUpdateAuditProgress: function(message) { var auditResult = this._clientObjects[message.resultId]; if (!auditResult) return this._status.E_NOTFOUND(message.resultId); auditResult.updateProgress(Math.min(Math.max(0, message.progress), 1)); }, _onStopAuditCategoryRun: function(message) { var auditRun = this._clientObjects[message.resultId]; if (!auditRun) return this._status.E_NOTFOUND(message.resultId); auditRun.done(); }, _dispatchCallback: function(requestId, port, result) { if (requestId) port.postMessage({ command: "callback", requestId: requestId, result: result }); }, initExtensions: function() { this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.ConsoleMessageAdded, WebInspector.console, WebInspector.ConsoleModel.Events.MessageAdded, this._notifyConsoleMessageAdded); this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.NetworkRequestFinished, WebInspector.networkManager, WebInspector.NetworkManager.EventTypes.RequestFinished, this._notifyRequestFinished); this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.ResourceAdded, WebInspector.workspace, WebInspector.UISourceCodeProvider.Events.UISourceCodeAdded, this._notifyResourceAdded); this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.ElementsPanelObjectSelected, WebInspector.notifications, WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged, this._notifyElementsSelectionChanged); this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.ResourceContentCommitted, WebInspector.workspace, WebInspector.Workspace.Events.UISourceCodeContentCommitted, this._notifyUISourceCodeContentCommitted); function onTimelineSubscriptionStarted() { WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.EventTypes.TimelineEventRecorded, this._notifyTimelineEventRecorded, this); WebInspector.timelineManager.start(); } function onTimelineSubscriptionStopped() { WebInspector.timelineManager.stop(); WebInspector.timelineManager.removeEventListener(WebInspector.TimelineManager.EventTypes.TimelineEventRecorded, this._notifyTimelineEventRecorded, this); } this._registerSubscriptionHandler(WebInspector.extensionAPI.Events.TimelineEventRecorded, onTimelineSubscriptionStarted.bind(this), onTimelineSubscriptionStopped.bind(this)); WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged, this._inspectedURLChanged, this); WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameNavigated, this); this._initDone = true; if (this._pendingExtensions) { this._pendingExtensions.forEach(this._innerAddExtension, this); delete this._pendingExtensions; } InspectorExtensionRegistry.getExtensionsAsync(); }, _notifyConsoleMessageAdded: function(event) { this._postNotification(WebInspector.extensionAPI.Events.ConsoleMessageAdded, this._makeConsoleMessage(event.data)); }, _notifyResourceAdded: function(event) { var uiSourceCode = (event.data); this._postNotification(WebInspector.extensionAPI.Events.ResourceAdded, this._makeResource(uiSourceCode)); }, _notifyUISourceCodeContentCommitted: function(event) { var uiSourceCode = (event.data.uiSourceCode); var content = (event.data.content); this._postNotification(WebInspector.extensionAPI.Events.ResourceContentCommitted, this._makeResource(uiSourceCode), content); }, _notifyRequestFinished: function(event) { var request = (event.data); this._postNotification(WebInspector.extensionAPI.Events.NetworkRequestFinished, this._requestId(request), (new WebInspector.HAREntry(request)).build()); }, _notifyElementsSelectionChanged: function() { this._postNotification(WebInspector.extensionAPI.Events.ElementsPanelObjectSelected); }, _notifyTimelineEventRecorded: function(event) { this._postNotification(WebInspector.extensionAPI.Events.TimelineEventRecorded, event.data); }, _addExtensions: function(extensions) { extensions.forEach(this._addExtension, this); }, _addExtension: function(extensionInfo) { if (this._initDone) { this._innerAddExtension(extensionInfo); return; } if (this._pendingExtensions) this._pendingExtensions.push(extensionInfo); else this._pendingExtensions = [extensionInfo]; }, _innerAddExtension: function(extensionInfo) { const urlOriginRegExp = new RegExp("([^:]+:\/\/[^/]*)\/"); var startPage = extensionInfo.startPage; var name = extensionInfo.name; try { var originMatch = urlOriginRegExp.exec(startPage); if (!originMatch) { console.error("Skipping extension with invalid URL: " + startPage); return false; } var extensionOrigin = originMatch[1]; if (!this._registeredExtensions[extensionOrigin]) { InspectorFrontendHost.setInjectedScriptForOrigin(extensionOrigin, buildExtensionAPIInjectedScript(extensionInfo)); this._registeredExtensions[extensionOrigin] = { name: name }; } var iframe = document.createElement("iframe"); iframe.src = startPage; iframe.style.display = "none"; document.body.appendChild(iframe); } catch (e) { console.error("Failed to initialize extension " + startPage + ":" + e); return false; } return true; }, _onWindowMessage: function(event) { if (event.data === "registerExtension") this._registerExtension(event.origin, event.ports[0]); }, _registerExtension: function(origin, port) { if (!this._registeredExtensions.hasOwnProperty(origin)) { if (origin !== window.location.origin) console.error("Ignoring unauthorized client request from " + origin); return; } port._extensionOrigin = origin; port.addEventListener("message", this._onmessage.bind(this), false); port.start(); }, _onmessage: function(event) { var message = event.data; var result; if (message.command in this._handlers) result = this._handlers[message.command](message, event.target); else result = this._status.E_NOTSUPPORTED(message.command); if (result && message.requestId) this._dispatchCallback(message.requestId, event.target, result); }, _registerHandler: function(command, callback) { this._handlers[command] = callback; }, _registerSubscriptionHandler: function(eventTopic, onSubscribeFirst, onUnsubscribeLast) { this._subscriptionStartHandlers[eventTopic] = onSubscribeFirst; this._subscriptionStopHandlers[eventTopic] = onUnsubscribeLast; }, _registerAutosubscriptionHandler: function(eventTopic, eventTarget, frontendEventType, handler) { this._registerSubscriptionHandler(eventTopic, eventTarget.addEventListener.bind(eventTarget, frontendEventType, handler, this), eventTarget.removeEventListener.bind(eventTarget, frontendEventType, handler, this)); }, _expandResourcePath: function(extensionPath, resourcePath) { if (!resourcePath) return; return extensionPath + this._normalizePath(resourcePath); }, _normalizePath: function(path) { var source = path.split("/"); var result = []; for (var i = 0; i < source.length; ++i) { if (source[i] === ".") continue; if (source[i] === "") continue; if (source[i] === "..") result.pop(); else result.push(source[i]); } return "/" + result.join("/"); }, evaluate: function(expression, exposeCommandLineAPI, returnByValue, options, securityOrigin, callback) { var contextId; if (typeof options === "object" && options["useContentScriptContext"]) { var mainFrame = WebInspector.resourceTreeModel.mainFrame; if (!mainFrame) return this._status.E_FAILED("main frame not available yet"); var context = WebInspector.runtimeModel.contextByFrameAndSecurityOrigin(mainFrame, securityOrigin); if (!context) return this._status.E_NOTFOUND(securityOrigin); contextId = context.id; } RuntimeAgent.evaluate(expression, "extension", exposeCommandLineAPI, true, contextId, returnByValue, false, callback); } } WebInspector.ExtensionStatus = function() { function makeStatus(code, description) { var details = Array.prototype.slice.call(arguments, 2); var status = { code: code, description: description, details: details }; if (code !== "OK") { status.isError = true; console.log("Extension server error: " + String.vsprintf(description, details)); } return status; } this.OK = makeStatus.bind(null, "OK", "OK"); this.E_EXISTS = makeStatus.bind(null, "E_EXISTS", "Object already exists: %s"); this.E_BADARG = makeStatus.bind(null, "E_BADARG", "Invalid argument %s: %s"); this.E_BADARGTYPE = makeStatus.bind(null, "E_BADARGTYPE", "Invalid type for argument %s: got %s, expected %s"); this.E_NOTFOUND = makeStatus.bind(null, "E_NOTFOUND", "Object not found: %s"); this.E_NOTSUPPORTED = makeStatus.bind(null, "E_NOTSUPPORTED", "Object does not support requested operation: %s"); this.E_FAILED = makeStatus.bind(null, "E_FAILED", "Operation failed: %s"); } WebInspector.addExtensions = function(extensions) { WebInspector.extensionServer._addExtensions(extensions); } WebInspector.extensionAPI = {}; defineCommonExtensionSymbols(WebInspector.extensionAPI); WebInspector.extensionServer = new WebInspector.ExtensionServer(); window.addExtension = function(page, name) { WebInspector.extensionServer._addExtension({ startPage: page, name: name, }); } WebInspector.ExtensionView = function(id, src, className) { WebInspector.View.call(this); this.element.className = "fill"; this._id = id; this._iframe = document.createElement("iframe"); this._iframe.addEventListener("load", this._onLoad.bind(this), false); this._iframe.src = src; this._iframe.className = className; this.setDefaultFocusedElement(this._iframe); this.element.appendChild(this._iframe); } WebInspector.ExtensionView.prototype = { wasShown: function() { if (typeof this._frameIndex === "number") WebInspector.extensionServer.notifyViewShown(this._id, this._frameIndex); }, willHide: function() { if (typeof this._frameIndex === "number") WebInspector.extensionServer.notifyViewHidden(this._id); }, _onLoad: function() { this._frameIndex = Array.prototype.indexOf.call(window.frames, this._iframe.contentWindow); if (this.isShowing()) WebInspector.extensionServer.notifyViewShown(this._id, this._frameIndex); }, __proto__: WebInspector.View.prototype } WebInspector.ExtensionNotifierView = function(id) { WebInspector.View.call(this); this._id = id; } WebInspector.ExtensionNotifierView.prototype = { wasShown: function() { WebInspector.extensionServer.notifyViewShown(this._id); }, willHide: function() { WebInspector.extensionServer.notifyViewHidden(this._id); }, __proto__: WebInspector.View.prototype } WebInspector.ExtensionPanel = function(id, pageURL) { WebInspector.Panel.call(this, id); this.setHideOnDetach(); this._statusBarItems = []; var extensionView = new WebInspector.ExtensionView(id, pageURL, "extension panel"); extensionView.show(this.element); this.setDefaultFocusedElement(extensionView.defaultFocusedElement()); } WebInspector.ExtensionPanel.prototype = { defaultFocusedElement: function() { return WebInspector.View.prototype.defaultFocusedElement.call(this); }, get statusBarItems() { return this._statusBarItems; }, addStatusBarItem: function(element) { this._statusBarItems.push(element); }, searchCanceled: function(startingNewSearch) { WebInspector.extensionServer.notifySearchAction(this.name, WebInspector.extensionAPI.panels.SearchAction.CancelSearch); WebInspector.Panel.prototype.searchCanceled.apply(this, arguments); }, performSearch: function(query) { WebInspector.extensionServer.notifySearchAction(this.name, WebInspector.extensionAPI.panels.SearchAction.PerformSearch, query); WebInspector.Panel.prototype.performSearch.apply(this, arguments); }, jumpToNextSearchResult: function() { WebInspector.extensionServer.notifySearchAction(this.name, WebInspector.extensionAPI.panels.SearchAction.NextSearchResult); WebInspector.Panel.prototype.jumpToNextSearchResult.call(this); }, jumpToPreviousSearchResult: function() { WebInspector.extensionServer.notifySearchAction(this.name, WebInspector.extensionAPI.panels.SearchAction.PreviousSearchResult); WebInspector.Panel.prototype.jumpToPreviousSearchResult.call(this); }, __proto__: WebInspector.Panel.prototype } WebInspector.ExtensionButton = function(id, iconURL, tooltip, disabled) { this._id = id; this.element = document.createElement("button"); this.element.className = "status-bar-item extension"; this.element.addEventListener("click", this._onClicked.bind(this), false); this.update(iconURL, tooltip, disabled); } WebInspector.ExtensionButton.prototype = { update: function(iconURL, tooltip, disabled) { if (typeof iconURL === "string") this.element.style.backgroundImage = "url(" + iconURL + ")"; if (typeof tooltip === "string") this.element.title = tooltip; if (typeof disabled === "boolean") this.element.disabled = disabled; }, _onClicked: function() { WebInspector.extensionServer.notifyButtonClicked(this._id); } } WebInspector.ExtensionSidebarPane = function(title, id) { WebInspector.SidebarPane.call(this, title); this._id = id; } WebInspector.ExtensionSidebarPane.prototype = { setObject: function(object, title, callback) { this._createObjectPropertiesView(); this._setObject(WebInspector.RemoteObject.fromLocalObject(object), title, callback); }, setExpression: function(expression, title, evaluateOptions, securityOrigin, callback) { this._createObjectPropertiesView(); return WebInspector.extensionServer.evaluate(expression, true, false, evaluateOptions, securityOrigin, this._onEvaluate.bind(this, title, callback)); }, setPage: function(url) { if (this._objectPropertiesView) { this._objectPropertiesView.detach(); delete this._objectPropertiesView; } if (this._extensionView) this._extensionView.detach(true); this._extensionView = new WebInspector.ExtensionView(this._id, url, "extension fill"); this._extensionView.show(this.bodyElement); if (!this.bodyElement.style.height) this.setHeight("150px"); }, setHeight: function(height) { this.bodyElement.style.height = height; }, _onEvaluate: function(title, callback, error, result, wasThrown) { if (error) callback(error.toString()); else this._setObject(WebInspector.RemoteObject.fromPayload(result), title, callback); }, _createObjectPropertiesView: function() { if (this._objectPropertiesView) return; if (this._extensionView) { this._extensionView.detach(true); delete this._extensionView; } this._objectPropertiesView = new WebInspector.ExtensionNotifierView(this._id); this._objectPropertiesView.show(this.bodyElement); }, _setObject: function(object, title, callback) { if (!this._objectPropertiesView) { callback("operation cancelled"); return; } this._objectPropertiesView.element.removeChildren(); var section = new WebInspector.ObjectPropertiesSection(object, title); if (!title) section.headerElement.addStyleClass("hidden"); section.expanded = true; section.editable = false; this._objectPropertiesView.element.appendChild(section.element); callback(); }, __proto__: WebInspector.SidebarPane.prototype } WebInspector.EmptyView = function(text) { WebInspector.View.call(this); this._text = text; } WebInspector.EmptyView.prototype = { wasShown: function() { this.element.className = "storage-empty-view"; this.element.textContent = this._text; }, set text(text) { this._text = text; if (this.isShowing()) this.element.textContent = this._text; }, __proto__: WebInspector.View.prototype } WebInspector.Formatter = function() { } WebInspector.Formatter.createFormatter = function(contentType) { if (contentType === WebInspector.resourceTypes.Script || contentType === WebInspector.resourceTypes.Document) return new WebInspector.ScriptFormatter(); return new WebInspector.IdentityFormatter(); } WebInspector.Formatter.locationToPosition = function(lineEndings, lineNumber, columnNumber) { var position = lineNumber ? lineEndings[lineNumber - 1] + 1 : 0; return position + columnNumber; } WebInspector.Formatter.positionToLocation = function(lineEndings, position) { var lineNumber = lineEndings.upperBound(position - 1); if (!lineNumber) var columnNumber = position; else var columnNumber = position - lineEndings[lineNumber - 1] - 1; return [lineNumber, columnNumber]; } WebInspector.Formatter.prototype = { formatContent: function(mimeType, content, callback) { } } WebInspector.ScriptFormatter = function() { this._tasks = []; } WebInspector.ScriptFormatter.prototype = { formatContent: function(mimeType, content, callback) { content = content.replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, ''); const method = "format"; var parameters = { mimeType: mimeType, content: content, indentString: WebInspector.settings.textEditorIndent.get() }; this._tasks.push({ data: parameters, callback: callback }); this._worker.postMessage({ method: method, params: parameters }); }, _didFormatContent: function(event) { var task = this._tasks.shift(); var originalContent = task.data.content; var formattedContent = event.data.content; var mapping = event.data["mapping"]; var sourceMapping = new WebInspector.FormatterSourceMappingImpl(originalContent.lineEndings(), formattedContent.lineEndings(), mapping); task.callback(formattedContent, sourceMapping); }, get _worker() { if (!this._cachedWorker) { this._cachedWorker = new Worker("ScriptFormatterWorker.js"); this._cachedWorker.onmessage = (this._didFormatContent.bind(this)); } return this._cachedWorker; } } WebInspector.IdentityFormatter = function() { this._tasks = []; } WebInspector.IdentityFormatter.prototype = { formatContent: function(mimeType, content, callback) { callback(content, new WebInspector.IdentityFormatterSourceMapping()); } } WebInspector.FormatterMappingPayload = function() { this.original = []; this.formatted = []; } WebInspector.FormatterSourceMapping = function() { } WebInspector.FormatterSourceMapping.prototype = { originalToFormatted: function(lineNumber, columnNumber) { }, formattedToOriginal: function(lineNumber, columnNumber) { } } WebInspector.IdentityFormatterSourceMapping = function() { } WebInspector.IdentityFormatterSourceMapping.prototype = { originalToFormatted: function(lineNumber, columnNumber) { return [lineNumber, columnNumber || 0]; }, formattedToOriginal: function(lineNumber, columnNumber) { return [lineNumber, columnNumber || 0]; } } WebInspector.FormatterSourceMappingImpl = function(originalLineEndings, formattedLineEndings, mapping) { this._originalLineEndings = originalLineEndings; this._formattedLineEndings = formattedLineEndings; this._mapping = mapping; } WebInspector.FormatterSourceMappingImpl.prototype = { originalToFormatted: function(lineNumber, columnNumber) { var originalPosition = WebInspector.Formatter.locationToPosition(this._originalLineEndings, lineNumber, columnNumber || 0); var formattedPosition = this._convertPosition(this._mapping.original, this._mapping.formatted, originalPosition || 0); return WebInspector.Formatter.positionToLocation(this._formattedLineEndings, formattedPosition); }, formattedToOriginal: function(lineNumber, columnNumber) { var formattedPosition = WebInspector.Formatter.locationToPosition(this._formattedLineEndings, lineNumber, columnNumber || 0); var originalPosition = this._convertPosition(this._mapping.formatted, this._mapping.original, formattedPosition); return WebInspector.Formatter.positionToLocation(this._originalLineEndings, originalPosition || 0); }, _convertPosition: function(positions1, positions2, position) { var index = positions1.upperBound(position) - 1; var convertedPosition = positions2[index] + position - positions1[index]; if (index < positions2.length - 1 && convertedPosition > positions2[index + 1]) convertedPosition = positions2[index + 1]; return convertedPosition; } } WebInspector.DOMSyntaxHighlighter = function(mimeType, stripExtraWhitespace) { this._tokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer(mimeType); this._stripExtraWhitespace = stripExtraWhitespace; } WebInspector.DOMSyntaxHighlighter.prototype = { createSpan: function(content, className) { var span = document.createElement("span"); span.className = "webkit-" + className; if (this._stripExtraWhitespace) content = content.replace(/^[\n\r]*/, "").replace(/\s*$/, ""); span.appendChild(document.createTextNode(content)); return span; }, syntaxHighlightNode: function(node) { this._tokenizer.condition = this._tokenizer.createInitialCondition(); var lines = node.textContent.split("\n"); node.removeChildren(); for (var i = lines[0].length ? 0 : 1; i < lines.length; ++i) { var line = lines[i]; var plainTextStart = 0; this._tokenizer.line = line; var column = 0; do { var newColumn = this._tokenizer.nextToken(column); var tokenType = this._tokenizer.tokenType; if (tokenType) { if (column > plainTextStart) { var plainText = line.substring(plainTextStart, column); node.appendChild(document.createTextNode(plainText)); } var token = line.substring(column, newColumn); node.appendChild(this.createSpan(token, tokenType)); plainTextStart = newColumn; } column = newColumn; } while (column < line.length) if (plainTextStart < line.length) { var plainText = line.substring(plainTextStart, line.length); node.appendChild(document.createTextNode(plainText)); } if (i < lines.length - 1) node.appendChild(document.createElement("br")); } } } WebInspector.TextRange = function(startLine, startColumn, endLine, endColumn) { this.startLine = startLine; this.startColumn = startColumn; this.endLine = endLine; this.endColumn = endColumn; } WebInspector.TextRange.createFromLocation = function(line, column) { return new WebInspector.TextRange(line, column, line, column); } WebInspector.TextRange.fromObject = function (serializedTextRange) { return new WebInspector.TextRange(serializedTextRange.startLine, serializedTextRange.startColumn, serializedTextRange.endLine, serializedTextRange.endColumn); } WebInspector.TextRange.prototype = { isEmpty: function() { return this.startLine === this.endLine && this.startColumn === this.endColumn; }, get linesCount() { return this.endLine - this.startLine; }, collapseToEnd: function() { return new WebInspector.TextRange(this.endLine, this.endColumn, this.endLine, this.endColumn); }, normalize: function() { if (this.startLine > this.endLine || (this.startLine === this.endLine && this.startColumn > this.endColumn)) return new WebInspector.TextRange(this.endLine, this.endColumn, this.startLine, this.startColumn); else return this; }, clone: function() { return new WebInspector.TextRange(this.startLine, this.startColumn, this.endLine, this.endColumn); }, serializeToObject: function() { var serializedTextRange = {}; serializedTextRange.startLine = this.startLine; serializedTextRange.startColumn = this.startColumn; serializedTextRange.endLine = this.endLine; serializedTextRange.endColumn = this.endColumn; return serializedTextRange; }, compareTo: function(other) { if (this.startLine > other.startLine) return 1; if (this.startLine < other.startLine) return -1; if (this.startColumn > other.startColumn) return 1; if (this.startColumn < other.startColumn) return -1; return 0; } } WebInspector.TextEditorCommand = function(newRange, originalText) { this.newRange = newRange; this.originalText = originalText; } WebInspector.TextEditorModel = function() { this._lines = [""]; this._attributes = []; this._undoStack = []; this._noPunctuationRegex = /[^ !%&()*+,-.:;<=>?\[\]\^{|}~]+/; this._lineBreak = "\n"; } WebInspector.TextEditorModel.Indent = { TwoSpaces: " ", FourSpaces: " ", EightSpaces: " ", TabCharacter: "\t" } WebInspector.TextEditorModel.Events = { TextChanged: "TextChanged" } WebInspector.TextEditorModel.endsWithBracketRegex = /[{(\[]\s*$/; WebInspector.TextEditorModel.prototype = { get linesCount() { return this._lines.length; }, text: function() { return this._lines.join(this._lineBreak); }, range: function() { return new WebInspector.TextRange(0, 0, this._lines.length - 1, this._lines[this._lines.length - 1].length); }, get lineBreak() { return this._lineBreak; }, line: function(lineNumber) { if (lineNumber >= this._lines.length) throw "Out of bounds:" + lineNumber; return this._lines[lineNumber]; }, lineLength: function(lineNumber) { return this._lines[lineNumber].length; }, setText: function(text) { text = text || ""; var range = this.range(); this._lineBreak = /\r\n/.test(text) ? "\r\n" : "\n"; var newRange = this._innerSetText(range, text); this.dispatchEventToListeners(WebInspector.TextEditorModel.Events.TextChanged, { oldRange: range, newRange: newRange}); }, editRange: function(range, text) { var originalText = this.copyRange(range); if (text === originalText) return range; var newRange = this._innerSetText(range, text); this._pushUndoableCommand(newRange, originalText); this.dispatchEventToListeners(WebInspector.TextEditorModel.Events.TextChanged, { oldRange: range, newRange: newRange }); return newRange; }, _innerSetText: function(range, text) { this._eraseRange(range); if (text === "") return new WebInspector.TextRange(range.startLine, range.startColumn, range.startLine, range.startColumn); var newLines = text.split(/\r?\n/); var prefix = this._lines[range.startLine].substring(0, range.startColumn); var suffix = this._lines[range.startLine].substring(range.startColumn); var postCaret = prefix.length; if (newLines.length === 1) { this._setLine(range.startLine, prefix + newLines[0] + suffix); postCaret += newLines[0].length; } else { this._setLine(range.startLine, prefix + newLines[0]); this._insertLines(range, newLines); this._setLine(range.startLine + newLines.length - 1, newLines[newLines.length - 1] + suffix); postCaret = newLines[newLines.length - 1].length; } return new WebInspector.TextRange(range.startLine, range.startColumn, range.startLine + newLines.length - 1, postCaret); }, _insertLines: function(range, newLines) { var lines = new Array(this._lines.length + newLines.length - 1); for (var i = 0; i <= range.startLine; ++i) lines[i] = this._lines[i]; for (var i = 1; i < newLines.length; ++i) lines[range.startLine + i] = newLines[i]; for (var i = range.startLine + newLines.length; i < lines.length; ++i) lines[i] = this._lines[i - newLines.length + 1]; this._lines = lines; var attributes = new Array(lines.length); var insertionIndex = range.startColumn ? range.startLine + 1 : range.startLine; for (var i = 0; i < insertionIndex; ++i) attributes[i] = this._attributes[i]; for (var i = insertionIndex + newLines.length - 1; i < attributes.length; ++i) attributes[i] = this._attributes[i - newLines.length + 1]; this._attributes = attributes; }, _eraseRange: function(range) { if (range.isEmpty()) return; var prefix = this._lines[range.startLine].substring(0, range.startColumn); var suffix = this._lines[range.endLine].substring(range.endColumn); if (range.endLine > range.startLine) { this._lines.splice(range.startLine + 1, range.endLine - range.startLine); this._attributes.splice(range.startColumn ? range.startLine + 1 : range.startLine, range.endLine - range.startLine); } this._setLine(range.startLine, prefix + suffix); }, _setLine: function(lineNumber, text) { this._lines[lineNumber] = text; }, wordRange: function(lineNumber, column) { return new WebInspector.TextRange(lineNumber, this.wordStart(lineNumber, column, true), lineNumber, this.wordEnd(lineNumber, column, true)); }, wordStart: function(lineNumber, column, gapless) { var line = this._lines[lineNumber]; var prefix = line.substring(0, column).split("").reverse().join(""); var prefixMatch = this._noPunctuationRegex.exec(prefix); return prefixMatch && (!gapless || prefixMatch.index === 0) ? column - prefixMatch.index - prefixMatch[0].length : column; }, wordEnd: function(lineNumber, column, gapless) { var line = this._lines[lineNumber]; var suffix = line.substring(column); var suffixMatch = this._noPunctuationRegex.exec(suffix); return suffixMatch && (!gapless || suffixMatch.index === 0) ? column + suffixMatch.index + suffixMatch[0].length : column; }, copyRange: function(range) { if (!range) range = this.range(); var clip = []; if (range.startLine === range.endLine) { clip.push(this._lines[range.startLine].substring(range.startColumn, range.endColumn)); return clip.join(this._lineBreak); } clip.push(this._lines[range.startLine].substring(range.startColumn)); for (var i = range.startLine + 1; i < range.endLine; ++i) clip.push(this._lines[i]); clip.push(this._lines[range.endLine].substring(0, range.endColumn)); return clip.join(this._lineBreak); }, setAttribute: function(line, name, value) { var attrs = this._attributes[line]; if (!attrs) { attrs = {}; this._attributes[line] = attrs; } attrs[name] = value; }, getAttribute: function(line, name) { var attrs = this._attributes[line]; return attrs ? attrs[name] : null; }, removeAttribute: function(line, name) { var attrs = this._attributes[line]; if (attrs) delete attrs[name]; }, _pushUndoableCommand: function(newRange, originalText) { var command = new WebInspector.TextEditorCommand(newRange.clone(), originalText); if (this._inUndo) this._redoStack.push(command); else { if (!this._inRedo) this._redoStack = []; this._undoStack.push(command); } return command; }, undo: function(beforeCallback, afterCallback) { if (!this._undoStack.length) return null; this._markRedoableState(); this._inUndo = true; var range = this._doUndo(this._undoStack, beforeCallback, afterCallback); delete this._inUndo; return range; }, redo: function(beforeCallback, afterCallback) { if (!this._redoStack || !this._redoStack.length) return null; this.markUndoableState(); this._inRedo = true; var range = this._doUndo(this._redoStack, beforeCallback, afterCallback); delete this._inRedo; return range; }, _doUndo: function(stack, beforeCallback, afterCallback) { var range = null; for (var i = stack.length - 1; i >= 0; --i) { var command = stack[i]; stack.length = i; if (beforeCallback) beforeCallback(); range = this.editRange(command.newRange, command.originalText); if (afterCallback) afterCallback(command.newRange, range); if (i > 0 && stack[i - 1].explicit) return range; } return range; }, markUndoableState: function() { if (this._undoStack.length) this._undoStack[this._undoStack.length - 1].explicit = true; }, _markRedoableState: function() { if (this._redoStack.length) this._redoStack[this._redoStack.length - 1].explicit = true; }, resetUndoStack: function() { this._undoStack = []; }, __proto__: WebInspector.Object.prototype } WebInspector.TextEditorHighlighter = function(textModel, damageCallback) { this._textModel = textModel; this._tokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/html"); this._damageCallback = damageCallback; this._highlightChunkLimit = 1000; } WebInspector.TextEditorHighlighter._MaxLineCount = 10000; WebInspector.TextEditorHighlighter.prototype = { set mimeType(mimeType) { var tokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer(mimeType); if (tokenizer) this._tokenizer = tokenizer; }, set highlightChunkLimit(highlightChunkLimit) { this._highlightChunkLimit = highlightChunkLimit; }, highlight: function(endLine, forceRun) { if (this._textModel.linesCount > WebInspector.TextEditorHighlighter._MaxLineCount) return; var state = this._textModel.getAttribute(endLine - 1, "highlight"); if (state && state.postConditionStringified) { return; } this._requestedEndLine = endLine; if (this._highlightTimer && !forceRun) { return; } var startLine = endLine; while (startLine > 0) { state = this._textModel.getAttribute(startLine - 1, "highlight"); if (state && state.postConditionStringified) break; startLine--; } this._highlightInChunks(startLine, endLine); }, updateHighlight: function(startLine, endLine) { if (this._textModel.linesCount > WebInspector.TextEditorHighlighter._MaxLineCount) return; this._clearHighlightState(startLine); if (startLine) { var state = this._textModel.getAttribute(startLine - 1, "highlight"); if (!state || !state.postConditionStringified) { return false; } } var restored = this._highlightLines(startLine, endLine); if (!restored) { for (var i = this._lastHighlightedLine; i < this._textModel.linesCount; ++i) { var state = this._textModel.getAttribute(i, "highlight"); if (!state && i > endLine) break; this._textModel.setAttribute(i, "highlight-outdated", state); this._textModel.removeAttribute(i, "highlight"); } if (this._highlightTimer) { clearTimeout(this._highlightTimer); this._requestedEndLine = endLine; this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, this._lastHighlightedLine, this._requestedEndLine), 10); } } return restored; }, _highlightInChunks: function(startLine, endLine) { delete this._highlightTimer; var state = this._textModel.getAttribute(this._requestedEndLine - 1, "highlight"); if (state && state.postConditionStringified) return; if (this._requestedEndLine !== endLine) { this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, startLine, this._requestedEndLine), 100); return; } if (this._requestedEndLine > this._textModel.linesCount) this._requestedEndLine = this._textModel.linesCount; this._highlightLines(startLine, this._requestedEndLine); if (this._lastHighlightedLine < this._requestedEndLine) this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, this._lastHighlightedLine, this._requestedEndLine), 10); }, _highlightLines: function(startLine, endLine) { var state = this._textModel.getAttribute(startLine - 1, "highlight"); var postConditionStringified = state ? state.postConditionStringified : JSON.stringify(this._tokenizer.createInitialCondition()); var tokensCount = 0; for (var lineNumber = startLine; lineNumber < endLine; ++lineNumber) { state = this._selectHighlightState(lineNumber, postConditionStringified); if (state.postConditionStringified) { postConditionStringified = state.postConditionStringified; } else { var lastHighlightedColumn = 0; if (state.midConditionStringified) { lastHighlightedColumn = state.lastHighlightedColumn; postConditionStringified = state.midConditionStringified; } var line = this._textModel.line(lineNumber); this._tokenizer.line = line; this._tokenizer.condition = JSON.parse(postConditionStringified); do { var newColumn = this._tokenizer.nextToken(lastHighlightedColumn); var tokenType = this._tokenizer.tokenType; if (tokenType) state[lastHighlightedColumn] = { length: newColumn - lastHighlightedColumn, tokenType: tokenType }; lastHighlightedColumn = newColumn; if (++tokensCount > this._highlightChunkLimit) break; } while (lastHighlightedColumn < line.length); postConditionStringified = JSON.stringify(this._tokenizer.condition); if (lastHighlightedColumn < line.length) { state.lastHighlightedColumn = lastHighlightedColumn; state.midConditionStringified = postConditionStringified; break; } else { delete state.lastHighlightedColumn; delete state.midConditionStringified; state.postConditionStringified = postConditionStringified; } } var nextLineState = this._textModel.getAttribute(lineNumber + 1, "highlight"); if (nextLineState && nextLineState.preConditionStringified === state.postConditionStringified) { ++lineNumber; this._damageCallback(startLine, lineNumber); for (; lineNumber < endLine; ++lineNumber) { state = this._textModel.getAttribute(lineNumber, "highlight"); if (!state || !state.postConditionStringified) break; } this._lastHighlightedLine = lineNumber; return true; } } this._damageCallback(startLine, lineNumber); this._lastHighlightedLine = lineNumber; return false; }, _selectHighlightState: function(lineNumber, preConditionStringified) { var state = this._textModel.getAttribute(lineNumber, "highlight"); if (state && state.preConditionStringified === preConditionStringified) return state; var outdatedState = this._textModel.getAttribute(lineNumber, "highlight-outdated"); if (outdatedState && outdatedState.preConditionStringified === preConditionStringified) { this._textModel.setAttribute(lineNumber, "highlight", outdatedState); this._textModel.setAttribute(lineNumber, "highlight-outdated", state); return outdatedState; } if (state) this._textModel.setAttribute(lineNumber, "highlight-outdated", state); state = {}; state.preConditionStringified = preConditionStringified; this._textModel.setAttribute(lineNumber, "highlight", state); return state; }, _clearHighlightState: function(lineNumber) { this._textModel.removeAttribute(lineNumber, "highlight"); this._textModel.removeAttribute(lineNumber, "highlight-outdated"); } } WebInspector.SourceTokenizer = function() { } WebInspector.SourceTokenizer.prototype = { set line(line) { this._line = line; }, set condition(condition) { this._condition = condition; }, get condition() { return this._condition; }, getLexCondition: function() { return this.condition.lexCondition; }, setLexCondition: function(lexCondition) { this.condition.lexCondition = lexCondition; }, _charAt: function(cursor) { return cursor < this._line.length ? this._line.charAt(cursor) : "\n"; }, createInitialCondition: function() { }, nextToken: function(cursor) { } } WebInspector.SourceTokenizer.Registry = function() { this._tokenizers = {}; this._tokenizerConstructors = { "text/css": "SourceCSSTokenizer", "text/html": "SourceHTMLTokenizer", "text/javascript": "SourceJavaScriptTokenizer", "text/x-scss": "SourceCSSTokenizer" }; } WebInspector.SourceTokenizer.Registry.getInstance = function() { if (!WebInspector.SourceTokenizer.Registry._instance) WebInspector.SourceTokenizer.Registry._instance = new WebInspector.SourceTokenizer.Registry(); return WebInspector.SourceTokenizer.Registry._instance; } WebInspector.SourceTokenizer.Registry.prototype = { getTokenizer: function(mimeType) { if (!this._tokenizerConstructors[mimeType]) return null; var tokenizerClass = this._tokenizerConstructors[mimeType]; var tokenizer = this._tokenizers[tokenizerClass]; if (!tokenizer) { tokenizer = new WebInspector[tokenizerClass](); this._tokenizers[tokenizerClass] = tokenizer; } return tokenizer; } } WebInspector.SourceCSSTokenizer = function() { WebInspector.SourceTokenizer.call(this); this._propertyKeywords = WebInspector.CSSCompletions.cssPropertiesMetainfoKeySet(); this._colorKeywords = WebInspector.CSSKeywordCompletions.colors(); this._valueKeywords = [ "above", "absolute", "activeborder", "activecaption", "afar", "after-white-space", "ahead", "alias", "all", "all-scroll", "alternate", "always", "amharic", "amharic-abegede", "antialiased", "appworkspace", "arabic-indic", "armenian", "asterisks", "auto", "avoid", "background", "backwards", "baseline", "below", "bidi-override", "binary", "bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box", "both", "bottom", "break-all", "break-word", "button", "button-bevel", "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "cambodian", "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret", "cell", "center", "checkbox", "circle", "cjk-earthly-branch", "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote", "col-resize", "collapse", "compact", "condensed", "contain", "content", "content-box", "context-menu", "continuous", "copy", "cover", "crop", "cross", "crosshair", "currentcolor", "cursive", "dashed", "decimal", "decimal-leading-zero", "default", "default-button", "destination-atop", "destination-in", "destination-out", "destination-over", "devanagari", "disc", "discard", "document", "dot-dash", "dot-dot-dash", "dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out", "element", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede", "ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er", "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er", "ethiopic-halehame-aa-et", "ethiopic-halehame-am-et", "ethiopic-halehame-gez", "ethiopic-halehame-om-et", "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et", "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig", "ew-resize", "expanded", "extra-condensed", "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "footnotes", "forwards", "from", "geometricPrecision", "georgian", "graytext", "groove", "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew", "help", "hidden", "hide", "higher", "highlight", "highlighttext", "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore", "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite", "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis", "inline-block", "inline-table", "inset", "inside", "intrinsic", "invert", "italic", "justify", "kannada", "katakana", "katakana-iroha", "khmer", "landscape", "lao", "large", "larger", "left", "level", "lighter", "line-through", "linear", "lines", "list-item", "listbox", "listitem", "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian", "lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian", "lower-roman", "lowercase", "ltr", "malayalam", "match", "media-controls-background", "media-current-time-display", "media-fullscreen-button", "media-mute-button", "media-play-button", "media-return-to-realtime-button", "media-rewind-button", "media-seek-back-button", "media-seek-forward-button", "media-slider", "media-sliderthumb", "media-time-remaining-display", "media-volume-slider", "media-volume-slider-container", "media-volume-sliderthumb", "medium", "menu", "menulist", "menulist-button", "menulist-text", "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic", "mix", "mongolian", "monospace", "move", "multiple", "myanmar", "n-resize", "narrower", "navy", "ne-resize", "nesw-resize", "no-close-quote", "no-drop", "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap", "ns-resize", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote", "optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset", "outside", "overlay", "overline", "padding", "padding-box", "painted", "paused", "persian", "plus-darker", "plus-lighter", "pointer", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d", "progress", "push-button", "radio", "read-only", "read-write", "read-write-plaintext-only", "relative", "repeat", "repeat-x", "repeat-y", "reset", "reverse", "rgb", "rgba", "ridge", "right", "round", "row-resize", "rtl", "run-in", "running", "s-resize", "sans-serif", "scroll", "scrollbar", "se-resize", "searchfield", "searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button", "searchfield-results-decoration", "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama", "single", "skip-white-space", "slide", "slider-horizontal", "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow", "small", "small-caps", "small-caption", "smaller", "solid", "somali", "source-atop", "source-in", "source-out", "source-over", "space", "square", "square-button", "start", "static", "status-bar", "stretch", "stroke", "sub", "subpixel-antialiased", "super", "sw-resize", "table", "table-caption", "table-cell", "table-column", "table-column-group", "table-footer-group", "table-header-group", "table-row", "table-row-group", "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai", "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight", "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er", "tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top", "transparent", "ultra-condensed", "ultra-expanded", "underline", "up", "upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal", "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted", "visibleStroke", "visual", "w-resize", "wait", "wave", "white", "wider", "window", "windowframe", "windowtext", "x-large", "x-small", "xor", "xx-large", "xx-small", "yellow", "-wap-marquee", "-webkit-activelink", "-webkit-auto", "-webkit-baseline-middle", "-webkit-body", "-webkit-box", "-webkit-center", "-webkit-control", "-webkit-focus-ring-color", "-webkit-grab", "-webkit-grabbing", "-webkit-gradient", "-webkit-inline-box", "-webkit-left", "-webkit-link", "-webkit-marquee", "-webkit-mini-control", "-webkit-nowrap", "-webkit-pictograph", "-webkit-right", "-webkit-small-control", "-webkit-text", "-webkit-xxx-large", "-webkit-zoom-in", "-webkit-zoom-out", ].keySet(); this._scssValueKeywords = [ "abs", "adjust-color", "adjust-hue", "alpha", "append", "ceil", "change-color", "comparable", "complement", "darken", "desaturate", "fade-in", "fade-out", "floor", "grayscale", "hue", "ie-hex-str", "invert", "join", "length", "lighten", "lightness", "max", "min", "mix", "nth", "opacify", "opacity", "percentage", "quote", "round", "saturate", "saturation", "scale-color", "transparentize", "type-of", "unit", "unitless", "unquote", "zip" ].keySet(); this._lexConditions = { INITIAL: 0, COMMENT: 1, DSTRING: 2, SSTRING: 3 }; this._parseConditions = { INITIAL: 0, PROPERTY: 1, PROPERTY_VALUE: 2, AT_RULE: 3, AT_MEDIA_RULE: 4 }; this.case_INITIAL = 1000; this.case_COMMENT = 1002; this.case_DSTRING = 1003; this.case_SSTRING = 1004; this.condition = this.createInitialCondition(); } WebInspector.SourceCSSTokenizer.SCSSAtRelatedKeywords = ["from", "if", "in", "through"].keySet(); WebInspector.SourceCSSTokenizer.MediaTypes = ["all", "aural", "braille", "embossed", "handheld", "import", "print", "projection", "screen", "tty", "tv"].keySet(); WebInspector.SourceCSSTokenizer.prototype = { createInitialCondition: function() { return { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL }; }, _stringToken: function(cursor, stringEnds) { if (this._isPropertyValue()) this.tokenType = "css-string"; else this.tokenType = null; return cursor; }, _isPropertyValue: function() { return this._condition.parseCondition === this._parseConditions.PROPERTY_VALUE || this._condition.parseCondition === this._parseConditions.AT_RULE; }, _setParseCondition: function(condition) { this._condition.parseCondition = condition; }, nextToken: function(cursor) { var cursorOnEnter = cursor; var gotoCase = 1; var YYMARKER; while (1) { switch (gotoCase) { case 1: var yych; var yyaccept = 0; if (this.getLexCondition() < 2) { if (this.getLexCondition() < 1) { { gotoCase = this.case_INITIAL; continue; }; } else { { gotoCase = this.case_COMMENT; continue; }; } } else { if (this.getLexCondition() < 3) { { gotoCase = this.case_DSTRING; continue; }; } else { { gotoCase = this.case_SSTRING; continue; }; } } case this.case_COMMENT: yych = this._charAt(cursor); if (yych <= '\f') { if (yych == '\n') { gotoCase = 4; continue; }; { gotoCase = 3; continue; }; } else { if (yych <= '\r') { gotoCase = 4; continue; }; if (yych == '*') { gotoCase = 6; continue; }; { gotoCase = 3; continue; }; } case 2: { this.tokenType = "css-comment"; return cursor; } case 3: yyaccept = 0; yych = this._charAt(YYMARKER = ++cursor); { gotoCase = 12; continue; }; case 4: ++cursor; { this.tokenType = null; return cursor; } case 6: yyaccept = 1; yych = this._charAt(YYMARKER = ++cursor); if (yych == '*') { gotoCase = 9; continue; }; if (yych != '/') { gotoCase = 11; continue; }; case 7: ++cursor; this.setLexCondition(this._lexConditions.INITIAL); { this.tokenType = "css-comment"; return cursor; } case 9: ++cursor; yych = this._charAt(cursor); if (yych == '*') { gotoCase = 9; continue; }; if (yych == '/') { gotoCase = 7; continue; }; case 11: yyaccept = 0; YYMARKER = ++cursor; yych = this._charAt(cursor); case 12: if (yych <= '\f') { if (yych == '\n') { gotoCase = 2; continue; }; { gotoCase = 11; continue; }; } else { if (yych <= '\r') { gotoCase = 2; continue; }; if (yych == '*') { gotoCase = 9; continue; }; { gotoCase = 11; continue; }; } case this.case_DSTRING: yych = this._charAt(cursor); if (yych <= '\r') { if (yych == '\n') { gotoCase = 17; continue; }; if (yych <= '\f') { gotoCase = 16; continue; }; { gotoCase = 17; continue; }; } else { if (yych <= '"') { if (yych <= '!') { gotoCase = 16; continue; }; { gotoCase = 19; continue; }; } else { if (yych == '\\') { gotoCase = 21; continue; }; { gotoCase = 16; continue; }; } } case 15: { return this._stringToken(cursor); } case 16: yyaccept = 0; yych = this._charAt(YYMARKER = ++cursor); { gotoCase = 23; continue; }; case 17: ++cursor; case 18: { this.tokenType = null; return cursor; } case 19: ++cursor; case 20: this.setLexCondition(this._lexConditions.INITIAL); { return this._stringToken(cursor, true); } case 21: yych = this._charAt(++cursor); if (yych <= 'e') { if (yych <= '\'') { if (yych == '"') { gotoCase = 22; continue; }; if (yych <= '&') { gotoCase = 18; continue; }; } else { if (yych <= '\\') { if (yych <= '[') { gotoCase = 18; continue; }; } else { if (yych != 'b') { gotoCase = 18; continue; }; } } } else { if (yych <= 'r') { if (yych <= 'm') { if (yych >= 'g') { gotoCase = 18; continue; }; } else { if (yych <= 'n') { gotoCase = 22; continue; }; if (yych <= 'q') { gotoCase = 18; continue; }; } } else { if (yych <= 't') { if (yych <= 's') { gotoCase = 18; continue; }; } else { if (yych != 'v') { gotoCase = 18; continue; }; } } } case 22: yyaccept = 0; YYMARKER = ++cursor; yych = this._charAt(cursor); case 23: if (yych <= '\r') { if (yych == '\n') { gotoCase = 15; continue; }; if (yych <= '\f') { gotoCase = 22; continue; }; { gotoCase = 15; continue; }; } else { if (yych <= '"') { if (yych <= '!') { gotoCase = 22; continue; }; { gotoCase = 26; continue; }; } else { if (yych != '\\') { gotoCase = 22; continue; }; } } ++cursor; yych = this._charAt(cursor); if (yych <= 'e') { if (yych <= '\'') { if (yych == '"') { gotoCase = 22; continue; }; if (yych >= '\'') { gotoCase = 22; continue; }; } else { if (yych <= '\\') { if (yych >= '\\') { gotoCase = 22; continue; }; } else { if (yych == 'b') { gotoCase = 22; continue; }; } } } else { if (yych <= 'r') { if (yych <= 'm') { if (yych <= 'f') { gotoCase = 22; continue; }; } else { if (yych <= 'n') { gotoCase = 22; continue; }; if (yych >= 'r') { gotoCase = 22; continue; }; } } else { if (yych <= 't') { if (yych >= 't') { gotoCase = 22; continue; }; } else { if (yych == 'v') { gotoCase = 22; continue; }; } } } cursor = YYMARKER; { gotoCase = 15; continue; }; case 26: ++cursor; yych = this._charAt(cursor); { gotoCase = 20; continue; }; case this.case_INITIAL: yych = this._charAt(cursor); if (yych <= ':') { if (yych <= '&') { if (yych <= '"') { if (yych <= ' ') { gotoCase = 29; continue; }; if (yych <= '!') { gotoCase = 31; continue; }; { gotoCase = 33; continue; }; } else { if (yych <= '#') { gotoCase = 34; continue; }; if (yych <= '$') { gotoCase = 35; continue; }; if (yych >= '&') { gotoCase = 31; continue; }; } } else { if (yych <= '-') { if (yych <= '\'') { gotoCase = 36; continue; }; if (yych >= '-') { gotoCase = 37; continue; }; } else { if (yych <= '.') { gotoCase = 38; continue; }; if (yych <= '/') { gotoCase = 39; continue; }; if (yych <= '9') { gotoCase = 40; continue; }; { gotoCase = 42; continue; }; } } } else { if (yych <= ']') { if (yych <= '=') { if (yych <= ';') { gotoCase = 44; continue; }; if (yych >= '=') { gotoCase = 31; continue; }; } else { if (yych <= '?') { gotoCase = 29; continue; }; if (yych != '\\') { gotoCase = 31; continue; }; } } else { if (yych <= 'z') { if (yych == '_') { gotoCase = 31; continue; }; if (yych >= 'a') { gotoCase = 31; continue; }; } else { if (yych <= '{') { gotoCase = 46; continue; }; if (yych == '}') { gotoCase = 48; continue; }; } } } case 29: ++cursor; case 30: { this.tokenType = null; return cursor; } case 31: ++cursor; yych = this._charAt(cursor); { gotoCase = 51; continue; }; case 32: { var token = this._line.substring(cursorOnEnter, cursor); this.tokenType = null; if (this._condition.parseCondition === this._parseConditions.INITIAL || this._condition.parseCondition === this._parseConditions.PROPERTY) { if (token.charAt(0) === "@") { this.tokenType = "css-at-rule"; this._setParseCondition(token === "@media" ? this._parseConditions.AT_MEDIA_RULE : this._parseConditions.AT_RULE); this._condition.atKeyword = token; } else if (this._condition.parseCondition === this._parseConditions.INITIAL) this.tokenType = "css-selector"; else if (this._propertyKeywords.hasOwnProperty(token)) this.tokenType = "css-property"; } else if (this._condition.parseCondition === this._parseConditions.AT_MEDIA_RULE || this._condition.parseCondition === this._parseConditions.AT_RULE) { if (WebInspector.SourceCSSTokenizer.SCSSAtRelatedKeywords.hasOwnProperty(token)) this.tokenType = "css-at-rule"; else if (WebInspector.SourceCSSTokenizer.MediaTypes.hasOwnProperty(token)) this.tokenType = "css-keyword"; } if (this.tokenType) return cursor; if (this._isPropertyValue()) { var firstChar = token.charAt(0); if (firstChar === "$") this.tokenType = "scss-variable"; else if (firstChar === "!") this.tokenType = "css-bang-keyword"; else if (this._condition.atKeyword === "@extend") this.tokenType = "css-selector"; else if (this._valueKeywords.hasOwnProperty(token) || this._scssValueKeywords.hasOwnProperty(token)) this.tokenType = "css-keyword"; else if (this._colorKeywords.hasOwnProperty(token)) { this.tokenType = "css-color"; } } else if (this._condition.parseCondition !== this._parseConditions.PROPERTY_VALUE) this.tokenType = "css-selector"; return cursor; } case 33: yyaccept = 0; yych = this._charAt(YYMARKER = ++cursor); if (yych <= '.') { if (yych <= '!') { if (yych <= '\f') { if (yych == '\n') { gotoCase = 32; continue; }; { gotoCase = 132; continue; }; } else { if (yych <= '\r') { gotoCase = 32; continue; }; if (yych <= ' ') { gotoCase = 132; continue; }; { gotoCase = 130; continue; }; } } else { if (yych <= '\'') { if (yych <= '"') { gotoCase = 116; continue; }; if (yych <= '%') { gotoCase = 132; continue; }; { gotoCase = 130; continue; }; } else { if (yych == '-') { gotoCase = 130; continue; }; { gotoCase = 132; continue; }; } } } else { if (yych <= '\\') { if (yych <= '=') { if (yych <= '9') { gotoCase = 130; continue; }; if (yych <= '<') { gotoCase = 132; continue; }; { gotoCase = 130; continue; }; } else { if (yych <= '?') { gotoCase = 132; continue; }; if (yych <= '[') { gotoCase = 130; continue; }; { gotoCase = 134; continue; }; } } else { if (yych <= '_') { if (yych == '^') { gotoCase = 132; continue; }; { gotoCase = 130; continue; }; } else { if (yych <= '`') { gotoCase = 132; continue; }; if (yych <= 'z') { gotoCase = 130; continue; }; { gotoCase = 132; continue; }; } } } case 34: yych = this._charAt(++cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 30; continue; }; if (yych <= '9') { gotoCase = 127; continue; }; { gotoCase = 30; continue; }; } else { if (yych <= 'Z') { gotoCase = 127; continue; }; if (yych <= '`') { gotoCase = 30; continue; }; if (yych <= 'z') { gotoCase = 127; continue; }; { gotoCase = 30; continue; }; } case 35: yych = this._charAt(++cursor); if (yych <= '<') { if (yych <= '\'') { if (yych <= ' ') { gotoCase = 30; continue; }; if (yych <= '"') { gotoCase = 124; continue; }; if (yych <= '%') { gotoCase = 30; continue; }; { gotoCase = 124; continue; }; } else { if (yych <= '-') { if (yych <= ',') { gotoCase = 30; continue; }; { gotoCase = 124; continue; }; } else { if (yych <= '.') { gotoCase = 30; continue; }; if (yych <= '9') { gotoCase = 124; continue; }; { gotoCase = 30; continue; }; } } } else { if (yych <= ']') { if (yych <= '?') { if (yych <= '=') { gotoCase = 124; continue; }; { gotoCase = 30; continue; }; } else { if (yych == '\\') { gotoCase = 30; continue; }; { gotoCase = 124; continue; }; } } else { if (yych <= '_') { if (yych <= '^') { gotoCase = 30; continue; }; { gotoCase = 124; continue; }; } else { if (yych <= '`') { gotoCase = 30; continue; }; if (yych <= 'z') { gotoCase = 124; continue; }; { gotoCase = 30; continue; }; } } } case 36: yyaccept = 0; yych = this._charAt(YYMARKER = ++cursor); if (yych <= '.') { if (yych <= '"') { if (yych <= '\f') { if (yych == '\n') { gotoCase = 32; continue; }; { gotoCase = 118; continue; }; } else { if (yych <= '\r') { gotoCase = 32; continue; }; if (yych <= ' ') { gotoCase = 118; continue; }; { gotoCase = 114; continue; }; } } else { if (yych <= '\'') { if (yych <= '%') { gotoCase = 118; continue; }; if (yych <= '&') { gotoCase = 114; continue; }; { gotoCase = 116; continue; }; } else { if (yych == '-') { gotoCase = 114; continue; }; { gotoCase = 118; continue; }; } } } else { if (yych <= '\\') { if (yych <= '=') { if (yych <= '9') { gotoCase = 114; continue; }; if (yych <= '<') { gotoCase = 118; continue; }; { gotoCase = 114; continue; }; } else { if (yych <= '?') { gotoCase = 118; continue; }; if (yych <= '[') { gotoCase = 114; continue; }; { gotoCase = 120; continue; }; } } else { if (yych <= '_') { if (yych == '^') { gotoCase = 118; continue; }; { gotoCase = 114; continue; }; } else { if (yych <= '`') { gotoCase = 118; continue; }; if (yych <= 'z') { gotoCase = 114; continue; }; { gotoCase = 118; continue; }; } } } case 37: yyaccept = 0; yych = this._charAt(YYMARKER = ++cursor); if (yych == '.') { gotoCase = 67; continue; }; if (yych <= '/') { gotoCase = 51; continue; }; if (yych <= '9') { gotoCase = 52; continue; }; { gotoCase = 51; continue; }; case 38: yych = this._charAt(++cursor); if (yych <= '/') { gotoCase = 30; continue; }; if (yych <= '9') { gotoCase = 70; continue; }; { gotoCase = 30; continue; }; case 39: yyaccept = 0; yych = this._charAt(YYMARKER = ++cursor); if (yych == '*') { gotoCase = 106; continue; }; { gotoCase = 51; continue; }; case 40: yyaccept = 1; yych = this._charAt(YYMARKER = ++cursor); switch (yych) { case '!': case '"': case '&': case '\'': case '-': case '/': case '=': case '@': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': case '[': case ']': case 'a': case 'b': case 'f': case 'h': case 'j': case 'l': case 'n': case 'o': case 'q': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': { gotoCase = 50; continue; }; case '%': { gotoCase = 69; continue; }; case '.': { gotoCase = 67; continue; }; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { gotoCase = 52; continue; }; case 'H': { gotoCase = 54; continue; }; case '_': { gotoCase = 55; continue; }; case 'c': { gotoCase = 56; continue; }; case 'd': { gotoCase = 57; continue; }; case 'e': { gotoCase = 58; continue; }; case 'g': { gotoCase = 59; continue; }; case 'i': { gotoCase = 60; continue; }; case 'k': { gotoCase = 61; continue; }; case 'm': { gotoCase = 62; continue; }; case 'p': { gotoCase = 63; continue; }; case 'r': { gotoCase = 64; continue; }; case 's': { gotoCase = 65; continue; }; case 't': { gotoCase = 66; continue; }; default: { gotoCase = 41; continue; }; } case 41: { if (this._isPropertyValue()) this.tokenType = "css-number"; else this.tokenType = null; return cursor; } case 42: ++cursor; { this.tokenType = null; if (this._condition.parseCondition === this._parseConditions.PROPERTY || this._condition.parseCondition === this._parseConditions.INITIAL) this._setParseCondition(this._parseConditions.PROPERTY_VALUE); return cursor; } case 44: ++cursor; { this.tokenType = null; this._setParseCondition(this._condition.openBraces ? this._parseConditions.PROPERTY : this._parseConditions.INITIAL); delete this._condition.atKeyword; return cursor; } case 46: ++cursor; { this.tokenType = "block-start"; this._condition.openBraces = (this._condition.openBraces || 0) + 1; if (this._condition.parseCondition === this._parseConditions.AT_MEDIA_RULE) this._setParseCondition(this._parseConditions.INITIAL); else this._setParseCondition(this._parseConditions.PROPERTY); return cursor; } case 48: ++cursor; { this.tokenType = "block-end"; if (this._condition.openBraces > 0) --this._condition.openBraces; this._setParseCondition(this._condition.openBraces ? this._parseConditions.PROPERTY : this._parseConditions.INITIAL); delete this._condition.atKeyword; return cursor; } case 50: ++cursor; yych = this._charAt(cursor); case 51: if (yych <= '<') { if (yych <= '\'') { if (yych <= ' ') { gotoCase = 32; continue; }; if (yych <= '"') { gotoCase = 50; continue; }; if (yych <= '%') { gotoCase = 32; continue; }; { gotoCase = 50; continue; }; } else { if (yych <= '-') { if (yych <= ',') { gotoCase = 32; continue; }; { gotoCase = 50; continue; }; } else { if (yych <= '.') { gotoCase = 32; continue; }; if (yych <= '9') { gotoCase = 50; continue; }; { gotoCase = 32; continue; }; } } } else { if (yych <= ']') { if (yych <= '?') { if (yych <= '=') { gotoCase = 50; continue; }; { gotoCase = 32; continue; }; } else { if (yych == '\\') { gotoCase = 32; continue; }; { gotoCase = 50; continue; }; } } else { if (yych <= '_') { if (yych <= '^') { gotoCase = 32; continue; }; { gotoCase = 50; continue; }; } else { if (yych <= '`') { gotoCase = 32; continue; }; if (yych <= 'z') { gotoCase = 50; continue; }; { gotoCase = 32; continue; }; } } } case 52: yyaccept = 1; YYMARKER = ++cursor; yych = this._charAt(cursor); switch (yych) { case '!': case '"': case '&': case '\'': case '-': case '/': case '=': case '@': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': case '[': case ']': case 'a': case 'b': case 'f': case 'h': case 'j': case 'l': case 'n': case 'o': case 'q': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': { gotoCase = 50; continue; }; case '%': { gotoCase = 69; continue; }; case '.': { gotoCase = 67; continue; }; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { gotoCase = 52; continue; }; case 'H': { gotoCase = 54; continue; }; case '_': { gotoCase = 55; continue; }; case 'c': { gotoCase = 56; continue; }; case 'd': { gotoCase = 57; continue; }; case 'e': { gotoCase = 58; continue; }; case 'g': { gotoCase = 59; continue; }; case 'i': { gotoCase = 60; continue; }; case 'k': { gotoCase = 61; continue; }; case 'm': { gotoCase = 62; continue; }; case 'p': { gotoCase = 63; continue; }; case 'r': { gotoCase = 64; continue; }; case 's': { gotoCase = 65; continue; }; case 't': { gotoCase = 66; continue; }; default: { gotoCase = 41; continue; }; } case 54: yych = this._charAt(++cursor); if (yych == 'z') { gotoCase = 65; continue; }; { gotoCase = 51; continue; }; case 55: yych = this._charAt(++cursor); if (yych == '_') { gotoCase = 103; continue; }; { gotoCase = 51; continue; }; case 56: yych = this._charAt(++cursor); if (yych == 'm') { gotoCase = 65; continue; }; { gotoCase = 51; continue; }; case 57: yych = this._charAt(++cursor); if (yych == 'e') { gotoCase = 102; continue; }; { gotoCase = 51; continue; }; case 58: yych = this._charAt(++cursor); if (yych == 'm') { gotoCase = 65; continue; }; if (yych == 'x') { gotoCase = 65; continue; }; { gotoCase = 51; continue; }; case 59: yych = this._charAt(++cursor); if (yych == 'r') { gotoCase = 100; continue; }; { gotoCase = 51; continue; }; case 60: yych = this._charAt(++cursor); if (yych == 'n') { gotoCase = 65; continue; }; { gotoCase = 51; continue; }; case 61: yych = this._charAt(++cursor); if (yych == 'H') { gotoCase = 99; continue; }; { gotoCase = 51; continue; }; case 62: yych = this._charAt(++cursor); if (yych == 'm') { gotoCase = 65; continue; }; if (yych == 's') { gotoCase = 65; continue; }; { gotoCase = 51; continue; }; case 63: yych = this._charAt(++cursor); if (yych <= 's') { if (yych == 'c') { gotoCase = 65; continue; }; { gotoCase = 51; continue; }; } else { if (yych <= 't') { gotoCase = 65; continue; }; if (yych == 'x') { gotoCase = 65; continue; }; { gotoCase = 51; continue; }; } case 64: yych = this._charAt(++cursor); if (yych == 'a') { gotoCase = 97; continue; }; if (yych == 'e') { gotoCase = 98; continue; }; { gotoCase = 51; continue; }; case 65: yych = this._charAt(++cursor); if (yych <= '<') { if (yych <= '\'') { if (yych <= ' ') { gotoCase = 41; continue; }; if (yych <= '"') { gotoCase = 50; continue; }; if (yych <= '%') { gotoCase = 41; continue; }; { gotoCase = 50; continue; }; } else { if (yych <= '-') { if (yych <= ',') { gotoCase = 41; continue; }; { gotoCase = 50; continue; }; } else { if (yych <= '.') { gotoCase = 41; continue; }; if (yych <= '9') { gotoCase = 50; continue; }; { gotoCase = 41; continue; }; } } } else { if (yych <= ']') { if (yych <= '?') { if (yych <= '=') { gotoCase = 50; continue; }; { gotoCase = 41; continue; }; } else { if (yych == '\\') { gotoCase = 41; continue; }; { gotoCase = 50; continue; }; } } else { if (yych <= '_') { if (yych <= '^') { gotoCase = 41; continue; }; { gotoCase = 50; continue; }; } else { if (yych <= '`') { gotoCase = 41; continue; }; if (yych <= 'z') { gotoCase = 50; continue; }; { gotoCase = 41; continue; }; } } } case 66: yych = this._charAt(++cursor); if (yych == 'u') { gotoCase = 95; continue; }; { gotoCase = 51; continue; }; case 67: yych = this._charAt(++cursor); if (yych <= '/') { gotoCase = 68; continue; }; if (yych <= '9') { gotoCase = 70; continue; }; case 68: cursor = YYMARKER; if (yyaccept <= 0) { { gotoCase = 32; continue; }; } else { { gotoCase = 41; continue; }; } case 69: yych = this._charAt(++cursor); { gotoCase = 41; continue; }; case 70: yyaccept = 1; YYMARKER = ++cursor; yych = this._charAt(cursor); if (yych <= 'f') { if (yych <= 'H') { if (yych <= '/') { if (yych == '%') { gotoCase = 69; continue; }; { gotoCase = 41; continue; }; } else { if (yych <= '9') { gotoCase = 70; continue; }; if (yych <= 'G') { gotoCase = 41; continue; }; { gotoCase = 82; continue; }; } } else { if (yych <= 'b') { if (yych == '_') { gotoCase = 74; continue; }; { gotoCase = 41; continue; }; } else { if (yych <= 'c') { gotoCase = 76; continue; }; if (yych <= 'd') { gotoCase = 79; continue; }; if (yych >= 'f') { gotoCase = 41; continue; }; } } } else { if (yych <= 'm') { if (yych <= 'i') { if (yych <= 'g') { gotoCase = 80; continue; }; if (yych <= 'h') { gotoCase = 41; continue; }; { gotoCase = 78; continue; }; } else { if (yych == 'k') { gotoCase = 83; continue; }; if (yych <= 'l') { gotoCase = 41; continue; }; { gotoCase = 77; continue; }; } } else { if (yych <= 'q') { if (yych == 'p') { gotoCase = 75; continue; }; { gotoCase = 41; continue; }; } else { if (yych <= 'r') { gotoCase = 73; continue; }; if (yych <= 's') { gotoCase = 69; continue; }; if (yych <= 't') { gotoCase = 81; continue; }; { gotoCase = 41; continue; }; } } } yych = this._charAt(++cursor); if (yych == 'm') { gotoCase = 69; continue; }; if (yych == 'x') { gotoCase = 69; continue; }; { gotoCase = 68; continue; }; case 73: yych = this._charAt(++cursor); if (yych == 'a') { gotoCase = 93; continue; }; if (yych == 'e') { gotoCase = 94; continue; }; { gotoCase = 68; continue; }; case 74: yych = this._charAt(++cursor); if (yych == '_') { gotoCase = 90; continue; }; { gotoCase = 68; continue; }; case 75: yych = this._charAt(++cursor); if (yych <= 's') { if (yych == 'c') { gotoCase = 69; continue; }; { gotoCase = 68; continue; }; } else { if (yych <= 't') { gotoCase = 69; continue; }; if (yych == 'x') { gotoCase = 69; continue; }; { gotoCase = 68; continue; }; } case 76: yych = this._charAt(++cursor); if (yych == 'm') { gotoCase = 69; continue; }; { gotoCase = 68; continue; }; case 77: yych = this._charAt(++cursor); if (yych == 'm') { gotoCase = 69; continue; }; if (yych == 's') { gotoCase = 69; continue; }; { gotoCase = 68; continue; }; case 78: yych = this._charAt(++cursor); if (yych == 'n') { gotoCase = 69; continue; }; { gotoCase = 68; continue; }; case 79: yych = this._charAt(++cursor); if (yych == 'e') { gotoCase = 89; continue; }; { gotoCase = 68; continue; }; case 80: yych = this._charAt(++cursor); if (yych == 'r') { gotoCase = 87; continue; }; { gotoCase = 68; continue; }; case 81: yych = this._charAt(++cursor); if (yych == 'u') { gotoCase = 85; continue; }; { gotoCase = 68; continue; }; case 82: yych = this._charAt(++cursor); if (yych == 'z') { gotoCase = 69; continue; }; { gotoCase = 68; continue; }; case 83: yych = this._charAt(++cursor); if (yych != 'H') { gotoCase = 68; continue; }; yych = this._charAt(++cursor); if (yych == 'z') { gotoCase = 69; continue; }; { gotoCase = 68; continue; }; case 85: yych = this._charAt(++cursor); if (yych != 'r') { gotoCase = 68; continue; }; yych = this._charAt(++cursor); if (yych == 'n') { gotoCase = 69; continue; }; { gotoCase = 68; continue; }; case 87: yych = this._charAt(++cursor); if (yych != 'a') { gotoCase = 68; continue; }; yych = this._charAt(++cursor); if (yych == 'd') { gotoCase = 69; continue; }; { gotoCase = 68; continue; }; case 89: yych = this._charAt(++cursor); if (yych == 'g') { gotoCase = 69; continue; }; { gotoCase = 68; continue; }; case 90: yych = this._charAt(++cursor); if (yych != 'q') { gotoCase = 68; continue; }; yych = this._charAt(++cursor); if (yych != 'e') { gotoCase = 68; continue; }; yych = this._charAt(++cursor); if (yych == 'm') { gotoCase = 69; continue; }; { gotoCase = 68; continue; }; case 93: yych = this._charAt(++cursor); if (yych == 'd') { gotoCase = 69; continue; }; { gotoCase = 68; continue; }; case 94: yych = this._charAt(++cursor); if (yych == 'm') { gotoCase = 69; continue; }; { gotoCase = 68; continue; }; case 95: yych = this._charAt(++cursor); if (yych != 'r') { gotoCase = 51; continue; }; yych = this._charAt(++cursor); if (yych == 'n') { gotoCase = 65; continue; }; { gotoCase = 51; continue; }; case 97: yych = this._charAt(++cursor); if (yych == 'd') { gotoCase = 65; continue; }; { gotoCase = 51; continue; }; case 98: yych = this._charAt(++cursor); if (yych == 'm') { gotoCase = 65; continue; }; { gotoCase = 51; continue; }; case 99: yych = this._charAt(++cursor); if (yych == 'z') { gotoCase = 65; continue; }; { gotoCase = 51; continue; }; case 100: yych = this._charAt(++cursor); if (yych != 'a') { gotoCase = 51; continue; }; yych = this._charAt(++cursor); if (yych == 'd') { gotoCase = 65; continue; }; { gotoCase = 51; continue; }; case 102: yych = this._charAt(++cursor); if (yych == 'g') { gotoCase = 65; continue; }; { gotoCase = 51; continue; }; case 103: yych = this._charAt(++cursor); if (yych != 'q') { gotoCase = 51; continue; }; yych = this._charAt(++cursor); if (yych != 'e') { gotoCase = 51; continue; }; yych = this._charAt(++cursor); if (yych == 'm') { gotoCase = 65; continue; }; { gotoCase = 51; continue; }; case 106: ++cursor; yych = this._charAt(cursor); if (yych <= '\f') { if (yych == '\n') { gotoCase = 110; continue; }; { gotoCase = 106; continue; }; } else { if (yych <= '\r') { gotoCase = 110; continue; }; if (yych != '*') { gotoCase = 106; continue; }; } case 108: ++cursor; yych = this._charAt(cursor); if (yych == '*') { gotoCase = 108; continue; }; if (yych == '/') { gotoCase = 112; continue; }; { gotoCase = 106; continue; }; case 110: ++cursor; this.setLexCondition(this._lexConditions.COMMENT); { this.tokenType = "css-comment"; return cursor; } case 112: ++cursor; { this.tokenType = "css-comment"; return cursor; } case 114: yyaccept = 0; YYMARKER = ++cursor; yych = this._charAt(cursor); if (yych <= '.') { if (yych <= '"') { if (yych <= '\f') { if (yych == '\n') { gotoCase = 32; continue; }; { gotoCase = 118; continue; }; } else { if (yych <= '\r') { gotoCase = 32; continue; }; if (yych <= ' ') { gotoCase = 118; continue; }; { gotoCase = 114; continue; }; } } else { if (yych <= '\'') { if (yych <= '%') { gotoCase = 118; continue; }; if (yych <= '&') { gotoCase = 114; continue; }; } else { if (yych == '-') { gotoCase = 114; continue; }; { gotoCase = 118; continue; }; } } } else { if (yych <= '\\') { if (yych <= '=') { if (yych <= '9') { gotoCase = 114; continue; }; if (yych <= '<') { gotoCase = 118; continue; }; { gotoCase = 114; continue; }; } else { if (yych <= '?') { gotoCase = 118; continue; }; if (yych <= '[') { gotoCase = 114; continue; }; { gotoCase = 120; continue; }; } } else { if (yych <= '_') { if (yych == '^') { gotoCase = 118; continue; }; { gotoCase = 114; continue; }; } else { if (yych <= '`') { gotoCase = 118; continue; }; if (yych <= 'z') { gotoCase = 114; continue; }; { gotoCase = 118; continue; }; } } } case 116: ++cursor; if ((yych = this._charAt(cursor)) <= '<') { if (yych <= '\'') { if (yych <= ' ') { gotoCase = 117; continue; }; if (yych <= '"') { gotoCase = 50; continue; }; if (yych >= '&') { gotoCase = 50; continue; }; } else { if (yych <= '-') { if (yych >= '-') { gotoCase = 50; continue; }; } else { if (yych <= '.') { gotoCase = 117; continue; }; if (yych <= '9') { gotoCase = 50; continue; }; } } } else { if (yych <= ']') { if (yych <= '?') { if (yych <= '=') { gotoCase = 50; continue; }; } else { if (yych != '\\') { gotoCase = 50; continue; }; } } else { if (yych <= '_') { if (yych >= '_') { gotoCase = 50; continue; }; } else { if (yych <= '`') { gotoCase = 117; continue; }; if (yych <= 'z') { gotoCase = 50; continue; }; } } } case 117: { return this._stringToken(cursor, true); } case 118: ++cursor; yych = this._charAt(cursor); if (yych <= '\r') { if (yych == '\n') { gotoCase = 68; continue; }; if (yych <= '\f') { gotoCase = 118; continue; }; { gotoCase = 68; continue; }; } else { if (yych <= '\'') { if (yych <= '&') { gotoCase = 118; continue; }; { gotoCase = 123; continue; }; } else { if (yych != '\\') { gotoCase = 118; continue; }; } } case 120: ++cursor; yych = this._charAt(cursor); if (yych <= 'a') { if (yych <= '!') { if (yych <= '\n') { if (yych <= '\t') { gotoCase = 68; continue; }; } else { if (yych != '\r') { gotoCase = 68; continue; }; } } else { if (yych <= '\'') { if (yych <= '"') { gotoCase = 118; continue; }; if (yych <= '&') { gotoCase = 68; continue; }; { gotoCase = 118; continue; }; } else { if (yych == '\\') { gotoCase = 118; continue; }; { gotoCase = 68; continue; }; } } } else { if (yych <= 'q') { if (yych <= 'f') { if (yych <= 'b') { gotoCase = 118; continue; }; if (yych <= 'e') { gotoCase = 68; continue; }; { gotoCase = 118; continue; }; } else { if (yych == 'n') { gotoCase = 118; continue; }; { gotoCase = 68; continue; }; } } else { if (yych <= 't') { if (yych == 's') { gotoCase = 68; continue; }; { gotoCase = 118; continue; }; } else { if (yych == 'v') { gotoCase = 118; continue; }; { gotoCase = 68; continue; }; } } } ++cursor; this.setLexCondition(this._lexConditions.SSTRING); { return this._stringToken(cursor); } case 123: yych = this._charAt(++cursor); { gotoCase = 117; continue; }; case 124: ++cursor; yych = this._charAt(cursor); if (yych <= '<') { if (yych <= '\'') { if (yych <= ' ') { gotoCase = 126; continue; }; if (yych <= '"') { gotoCase = 124; continue; }; if (yych >= '&') { gotoCase = 124; continue; }; } else { if (yych <= '-') { if (yych >= '-') { gotoCase = 124; continue; }; } else { if (yych <= '.') { gotoCase = 126; continue; }; if (yych <= '9') { gotoCase = 124; continue; }; } } } else { if (yych <= ']') { if (yych <= '?') { if (yych <= '=') { gotoCase = 124; continue; }; } else { if (yych != '\\') { gotoCase = 124; continue; }; } } else { if (yych <= '_') { if (yych >= '_') { gotoCase = 124; continue; }; } else { if (yych <= '`') { gotoCase = 126; continue; }; if (yych <= 'z') { gotoCase = 124; continue; }; } } } case 126: { if (this._condition.parseCondition === this._condition.parseCondition.INITIAL || this._condition.parseCondition === this._condition.parseCondition.AT_RULE) this._setParseCondition(this._parseConditions.PROPERTY); this.tokenType = "scss-variable"; return cursor; } case 127: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 129; continue; }; if (yych <= '9') { gotoCase = 127; continue; }; } else { if (yych <= 'Z') { gotoCase = 127; continue; }; if (yych <= '`') { gotoCase = 129; continue; }; if (yych <= 'z') { gotoCase = 127; continue; }; } case 129: { if (this._isPropertyValue()) this.tokenType = "css-color"; else if (this._condition.parseCondition === this._parseConditions.INITIAL) this.tokenType = "css-selector"; else this.tokenType = null; return cursor; } case 130: yyaccept = 0; YYMARKER = ++cursor; yych = this._charAt(cursor); if (yych <= '.') { if (yych <= '!') { if (yych <= '\f') { if (yych == '\n') { gotoCase = 32; continue; }; } else { if (yych <= '\r') { gotoCase = 32; continue; }; if (yych >= '!') { gotoCase = 130; continue; }; } } else { if (yych <= '\'') { if (yych <= '"') { gotoCase = 116; continue; }; if (yych >= '&') { gotoCase = 130; continue; }; } else { if (yych == '-') { gotoCase = 130; continue; }; } } } else { if (yych <= '\\') { if (yych <= '=') { if (yych <= '9') { gotoCase = 130; continue; }; if (yych >= '=') { gotoCase = 130; continue; }; } else { if (yych <= '?') { gotoCase = 132; continue; }; if (yych <= '[') { gotoCase = 130; continue; }; { gotoCase = 134; continue; }; } } else { if (yych <= '_') { if (yych != '^') { gotoCase = 130; continue; }; } else { if (yych <= '`') { gotoCase = 132; continue; }; if (yych <= 'z') { gotoCase = 130; continue; }; } } } case 132: ++cursor; yych = this._charAt(cursor); if (yych <= '\r') { if (yych == '\n') { gotoCase = 68; continue; }; if (yych <= '\f') { gotoCase = 132; continue; }; { gotoCase = 68; continue; }; } else { if (yych <= '"') { if (yych <= '!') { gotoCase = 132; continue; }; { gotoCase = 123; continue; }; } else { if (yych != '\\') { gotoCase = 132; continue; }; } } case 134: ++cursor; yych = this._charAt(cursor); if (yych <= 'a') { if (yych <= '!') { if (yych <= '\n') { if (yych <= '\t') { gotoCase = 68; continue; }; } else { if (yych != '\r') { gotoCase = 68; continue; }; } } else { if (yych <= '\'') { if (yych <= '"') { gotoCase = 132; continue; }; if (yych <= '&') { gotoCase = 68; continue; }; { gotoCase = 132; continue; }; } else { if (yych == '\\') { gotoCase = 132; continue; }; { gotoCase = 68; continue; }; } } } else { if (yych <= 'q') { if (yych <= 'f') { if (yych <= 'b') { gotoCase = 132; continue; }; if (yych <= 'e') { gotoCase = 68; continue; }; { gotoCase = 132; continue; }; } else { if (yych == 'n') { gotoCase = 132; continue; }; { gotoCase = 68; continue; }; } } else { if (yych <= 't') { if (yych == 's') { gotoCase = 68; continue; }; { gotoCase = 132; continue; }; } else { if (yych == 'v') { gotoCase = 132; continue; }; { gotoCase = 68; continue; }; } } } ++cursor; this.setLexCondition(this._lexConditions.DSTRING); { return this._stringToken(cursor); } case this.case_SSTRING: yych = this._charAt(cursor); if (yych <= '\r') { if (yych == '\n') { gotoCase = 141; continue; }; if (yych <= '\f') { gotoCase = 140; continue; }; { gotoCase = 141; continue; }; } else { if (yych <= '\'') { if (yych <= '&') { gotoCase = 140; continue; }; { gotoCase = 143; continue; }; } else { if (yych == '\\') { gotoCase = 145; continue; }; { gotoCase = 140; continue; }; } } case 139: { return this._stringToken(cursor); } case 140: yyaccept = 0; yych = this._charAt(YYMARKER = ++cursor); { gotoCase = 147; continue; }; case 141: ++cursor; case 142: { this.tokenType = null; return cursor; } case 143: ++cursor; case 144: this.setLexCondition(this._lexConditions.INITIAL); { return this._stringToken(cursor, true); } case 145: yych = this._charAt(++cursor); if (yych <= 'e') { if (yych <= '\'') { if (yych == '"') { gotoCase = 146; continue; }; if (yych <= '&') { gotoCase = 142; continue; }; } else { if (yych <= '\\') { if (yych <= '[') { gotoCase = 142; continue; }; } else { if (yych != 'b') { gotoCase = 142; continue; }; } } } else { if (yych <= 'r') { if (yych <= 'm') { if (yych >= 'g') { gotoCase = 142; continue; }; } else { if (yych <= 'n') { gotoCase = 146; continue; }; if (yych <= 'q') { gotoCase = 142; continue; }; } } else { if (yych <= 't') { if (yych <= 's') { gotoCase = 142; continue; }; } else { if (yych != 'v') { gotoCase = 142; continue; }; } } } case 146: yyaccept = 0; YYMARKER = ++cursor; yych = this._charAt(cursor); case 147: if (yych <= '\r') { if (yych == '\n') { gotoCase = 139; continue; }; if (yych <= '\f') { gotoCase = 146; continue; }; { gotoCase = 139; continue; }; } else { if (yych <= '\'') { if (yych <= '&') { gotoCase = 146; continue; }; { gotoCase = 150; continue; }; } else { if (yych != '\\') { gotoCase = 146; continue; }; } } ++cursor; yych = this._charAt(cursor); if (yych <= 'e') { if (yych <= '\'') { if (yych == '"') { gotoCase = 146; continue; }; if (yych >= '\'') { gotoCase = 146; continue; }; } else { if (yych <= '\\') { if (yych >= '\\') { gotoCase = 146; continue; }; } else { if (yych == 'b') { gotoCase = 146; continue; }; } } } else { if (yych <= 'r') { if (yych <= 'm') { if (yych <= 'f') { gotoCase = 146; continue; }; } else { if (yych <= 'n') { gotoCase = 146; continue; }; if (yych >= 'r') { gotoCase = 146; continue; }; } } else { if (yych <= 't') { if (yych >= 't') { gotoCase = 146; continue; }; } else { if (yych == 'v') { gotoCase = 146; continue; }; } } } cursor = YYMARKER; { gotoCase = 139; continue; }; case 150: ++cursor; yych = this._charAt(cursor); { gotoCase = 144; continue; }; } } }, __proto__: WebInspector.SourceTokenizer.prototype } WebInspector.SourceHTMLTokenizer = function() { WebInspector.SourceTokenizer.call(this); this._lexConditions = { INITIAL: 0, COMMENT: 1, DOCTYPE: 2, TAG: 3, DSTRING: 4, SSTRING: 5 }; this.case_INITIAL = 1000; this.case_COMMENT = 1001; this.case_DOCTYPE = 1002; this.case_TAG = 1003; this.case_DSTRING = 1004; this.case_SSTRING = 1005; this._parseConditions = { INITIAL: 0, ATTRIBUTE: 1, ATTRIBUTE_VALUE: 2, LINKIFY: 4, A_NODE: 8, SCRIPT: 16, STYLE: 32 }; this.condition = this.createInitialCondition(); } WebInspector.SourceHTMLTokenizer.prototype = { createInitialCondition: function() { return { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL }; }, set line(line) { if (this._condition.internalJavaScriptTokenizerCondition) { var match = /<\/script/i.exec(line); if (match) { this._internalJavaScriptTokenizer.line = line.substring(0, match.index); } else this._internalJavaScriptTokenizer.line = line; } else if (this._condition.internalCSSTokenizerCondition) { var match = /<\/style/i.exec(line); if (match) { this._internalCSSTokenizer.line = line.substring(0, match.index); } else this._internalCSSTokenizer.line = line; } this._line = line; }, _isExpectingAttribute: function() { return this._condition.parseCondition & this._parseConditions.ATTRIBUTE; }, _isExpectingAttributeValue: function() { return this._condition.parseCondition & this._parseConditions.ATTRIBUTE_VALUE; }, _setExpectingAttribute: function() { if (this._isExpectingAttributeValue()) this._condition.parseCondition ^= this._parseConditions.ATTRIBUTE_VALUE; this._condition.parseCondition |= this._parseConditions.ATTRIBUTE; }, _setExpectingAttributeValue: function() { if (this._isExpectingAttribute()) this._condition.parseCondition ^= this._parseConditions.ATTRIBUTE; this._condition.parseCondition |= this._parseConditions.ATTRIBUTE_VALUE; }, _stringToken: function(cursor, stringEnds) { if (!this._isExpectingAttributeValue()) { this.tokenType = null; return cursor; } this.tokenType = this._attrValueTokenType(); if (stringEnds) this._setExpectingAttribute(); return cursor; }, _attrValueTokenType: function() { if (this._condition.parseCondition & this._parseConditions.LINKIFY) { if (this._condition.parseCondition & this._parseConditions.A_NODE) return "html-external-link"; return "html-resource-link"; } return "html-attribute-value"; }, get _internalJavaScriptTokenizer() { return WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/javascript"); }, get _internalCSSTokenizer() { return WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/css"); }, scriptStarted: function(cursor) { this._condition.internalJavaScriptTokenizerCondition = this._internalJavaScriptTokenizer.createInitialCondition(); }, scriptEnded: function(cursor) { }, styleSheetStarted: function(cursor) { this._condition.internalCSSTokenizerCondition = this._internalCSSTokenizer.createInitialCondition(); }, styleSheetEnded: function(cursor) { }, nextToken: function(cursor) { if (this._condition.internalJavaScriptTokenizerCondition) { this.line = this._line; if (cursor !== this._internalJavaScriptTokenizer._line.length) { this._internalJavaScriptTokenizer.condition = this._condition.internalJavaScriptTokenizerCondition; var result = this._internalJavaScriptTokenizer.nextToken(cursor); this.tokenType = this._internalJavaScriptTokenizer.tokenType; this._condition.internalJavaScriptTokenizerCondition = this._internalJavaScriptTokenizer.condition; return result; } else if (cursor !== this._line.length) delete this._condition.internalJavaScriptTokenizerCondition; } else if (this._condition.internalCSSTokenizerCondition) { this.line = this._line; if (cursor !== this._internalCSSTokenizer._line.length) { this._internalCSSTokenizer.condition = this._condition.internalCSSTokenizerCondition; var result = this._internalCSSTokenizer.nextToken(cursor); this.tokenType = this._internalCSSTokenizer.tokenType; this._condition.internalCSSTokenizerCondition = this._internalCSSTokenizer.condition; return result; } else if (cursor !== this._line.length) delete this._condition.internalCSSTokenizerCondition; } var cursorOnEnter = cursor; var gotoCase = 1; var YYMARKER; while (1) { switch (gotoCase) { case 1: var yych; var yyaccept = 0; if (this.getLexCondition() < 3) { if (this.getLexCondition() < 1) { { gotoCase = this.case_INITIAL; continue; }; } else { if (this.getLexCondition() < 2) { { gotoCase = this.case_COMMENT; continue; }; } else { { gotoCase = this.case_DOCTYPE; continue; }; } } } else { if (this.getLexCondition() < 4) { { gotoCase = this.case_TAG; continue; }; } else { if (this.getLexCondition() < 5) { { gotoCase = this.case_DSTRING; continue; }; } else { { gotoCase = this.case_SSTRING; continue; }; } } } case this.case_COMMENT: yych = this._charAt(cursor); if (yych <= '\f') { if (yych == '\n') { gotoCase = 4; continue; }; { gotoCase = 3; continue; }; } else { if (yych <= '\r') { gotoCase = 4; continue; }; if (yych == '-') { gotoCase = 6; continue; }; { gotoCase = 3; continue; }; } case 2: { this.tokenType = "html-comment"; return cursor; } case 3: yyaccept = 0; yych = this._charAt(YYMARKER = ++cursor); { gotoCase = 9; continue; }; case 4: ++cursor; case 5: { this.tokenType = null; return cursor; } case 6: yyaccept = 1; yych = this._charAt(YYMARKER = ++cursor); if (yych != '-') { gotoCase = 5; continue; }; case 7: ++cursor; yych = this._charAt(cursor); if (yych == '>') { gotoCase = 10; continue; }; case 8: yyaccept = 0; YYMARKER = ++cursor; yych = this._charAt(cursor); case 9: if (yych <= '\f') { if (yych == '\n') { gotoCase = 2; continue; }; { gotoCase = 8; continue; }; } else { if (yych <= '\r') { gotoCase = 2; continue; }; if (yych == '-') { gotoCase = 12; continue; }; { gotoCase = 8; continue; }; } case 10: ++cursor; this.setLexCondition(this._lexConditions.INITIAL); { this.tokenType = "html-comment"; return cursor; } case 12: ++cursor; yych = this._charAt(cursor); if (yych == '-') { gotoCase = 7; continue; }; cursor = YYMARKER; if (yyaccept <= 0) { { gotoCase = 2; continue; }; } else { { gotoCase = 5; continue; }; } case this.case_DOCTYPE: yych = this._charAt(cursor); if (yych <= '\f') { if (yych == '\n') { gotoCase = 18; continue; }; { gotoCase = 17; continue; }; } else { if (yych <= '\r') { gotoCase = 18; continue; }; if (yych == '>') { gotoCase = 20; continue; }; { gotoCase = 17; continue; }; } case 16: { this.tokenType = "html-doctype"; return cursor; } case 17: yych = this._charAt(++cursor); { gotoCase = 23; continue; }; case 18: ++cursor; { this.tokenType = null; return cursor; } case 20: ++cursor; this.setLexCondition(this._lexConditions.INITIAL); { this.tokenType = "html-doctype"; return cursor; } case 22: ++cursor; yych = this._charAt(cursor); case 23: if (yych <= '\f') { if (yych == '\n') { gotoCase = 16; continue; }; { gotoCase = 22; continue; }; } else { if (yych <= '\r') { gotoCase = 16; continue; }; if (yych == '>') { gotoCase = 16; continue; }; { gotoCase = 22; continue; }; } case this.case_DSTRING: yych = this._charAt(cursor); if (yych <= '\f') { if (yych == '\n') { gotoCase = 28; continue; }; { gotoCase = 27; continue; }; } else { if (yych <= '\r') { gotoCase = 28; continue; }; if (yych == '"') { gotoCase = 30; continue; }; { gotoCase = 27; continue; }; } case 26: { return this._stringToken(cursor); } case 27: yych = this._charAt(++cursor); { gotoCase = 34; continue; }; case 28: ++cursor; { this.tokenType = null; return cursor; } case 30: ++cursor; case 31: this.setLexCondition(this._lexConditions.TAG); { return this._stringToken(cursor, true); } case 32: yych = this._charAt(++cursor); { gotoCase = 31; continue; }; case 33: ++cursor; yych = this._charAt(cursor); case 34: if (yych <= '\f') { if (yych == '\n') { gotoCase = 26; continue; }; { gotoCase = 33; continue; }; } else { if (yych <= '\r') { gotoCase = 26; continue; }; if (yych == '"') { gotoCase = 32; continue; }; { gotoCase = 33; continue; }; } case this.case_INITIAL: yych = this._charAt(cursor); if (yych == '<') { gotoCase = 39; continue; }; ++cursor; { this.tokenType = null; return cursor; } case 39: yyaccept = 0; yych = this._charAt(YYMARKER = ++cursor); if (yych <= '/') { if (yych == '!') { gotoCase = 44; continue; }; if (yych >= '/') { gotoCase = 41; continue; }; } else { if (yych <= 'S') { if (yych >= 'S') { gotoCase = 42; continue; }; } else { if (yych == 's') { gotoCase = 42; continue; }; } } case 40: this.setLexCondition(this._lexConditions.TAG); { if (this._condition.parseCondition & (this._parseConditions.SCRIPT | this._parseConditions.STYLE)) { this.setLexCondition(this._lexConditions.INITIAL); this.tokenType = null; return cursor; } this._condition.parseCondition = this._parseConditions.INITIAL; this.tokenType = "html-tag"; return cursor; } case 41: yyaccept = 0; yych = this._charAt(YYMARKER = ++cursor); if (yych == 'S') { gotoCase = 73; continue; }; if (yych == 's') { gotoCase = 73; continue; }; { gotoCase = 40; continue; }; case 42: yych = this._charAt(++cursor); if (yych <= 'T') { if (yych == 'C') { gotoCase = 62; continue; }; if (yych >= 'T') { gotoCase = 63; continue; }; } else { if (yych <= 'c') { if (yych >= 'c') { gotoCase = 62; continue; }; } else { if (yych == 't') { gotoCase = 63; continue; }; } } case 43: cursor = YYMARKER; { gotoCase = 40; continue; }; case 44: yych = this._charAt(++cursor); if (yych <= 'C') { if (yych != '-') { gotoCase = 43; continue; }; } else { if (yych <= 'D') { gotoCase = 46; continue; }; if (yych == 'd') { gotoCase = 46; continue; }; { gotoCase = 43; continue; }; } yych = this._charAt(++cursor); if (yych == '-') { gotoCase = 54; continue; }; { gotoCase = 43; continue; }; case 46: yych = this._charAt(++cursor); if (yych == 'O') { gotoCase = 47; continue; }; if (yych != 'o') { gotoCase = 43; continue; }; case 47: yych = this._charAt(++cursor); if (yych == 'C') { gotoCase = 48; continue; }; if (yych != 'c') { gotoCase = 43; continue; }; case 48: yych = this._charAt(++cursor); if (yych == 'T') { gotoCase = 49; continue; }; if (yych != 't') { gotoCase = 43; continue; }; case 49: yych = this._charAt(++cursor); if (yych == 'Y') { gotoCase = 50; continue; }; if (yych != 'y') { gotoCase = 43; continue; }; case 50: yych = this._charAt(++cursor); if (yych == 'P') { gotoCase = 51; continue; }; if (yych != 'p') { gotoCase = 43; continue; }; case 51: yych = this._charAt(++cursor); if (yych == 'E') { gotoCase = 52; continue; }; if (yych != 'e') { gotoCase = 43; continue; }; case 52: ++cursor; this.setLexCondition(this._lexConditions.DOCTYPE); { this.tokenType = "html-doctype"; return cursor; } case 54: ++cursor; yych = this._charAt(cursor); if (yych <= '\f') { if (yych == '\n') { gotoCase = 57; continue; }; { gotoCase = 54; continue; }; } else { if (yych <= '\r') { gotoCase = 57; continue; }; if (yych != '-') { gotoCase = 54; continue; }; } ++cursor; yych = this._charAt(cursor); if (yych == '-') { gotoCase = 59; continue; }; { gotoCase = 43; continue; }; case 57: ++cursor; this.setLexCondition(this._lexConditions.COMMENT); { this.tokenType = "html-comment"; return cursor; } case 59: ++cursor; yych = this._charAt(cursor); if (yych != '>') { gotoCase = 54; continue; }; ++cursor; { this.tokenType = "html-comment"; return cursor; } case 62: yych = this._charAt(++cursor); if (yych == 'R') { gotoCase = 68; continue; }; if (yych == 'r') { gotoCase = 68; continue; }; { gotoCase = 43; continue; }; case 63: yych = this._charAt(++cursor); if (yych == 'Y') { gotoCase = 64; continue; }; if (yych != 'y') { gotoCase = 43; continue; }; case 64: yych = this._charAt(++cursor); if (yych == 'L') { gotoCase = 65; continue; }; if (yych != 'l') { gotoCase = 43; continue; }; case 65: yych = this._charAt(++cursor); if (yych == 'E') { gotoCase = 66; continue; }; if (yych != 'e') { gotoCase = 43; continue; }; case 66: ++cursor; this.setLexCondition(this._lexConditions.TAG); { if (this._condition.parseCondition & this._parseConditions.STYLE) { this.setLexCondition(this._lexConditions.INITIAL); this.tokenType = null; return cursor; } this.tokenType = "html-tag"; this._condition.parseCondition = this._parseConditions.STYLE; this._setExpectingAttribute(); return cursor; } case 68: yych = this._charAt(++cursor); if (yych == 'I') { gotoCase = 69; continue; }; if (yych != 'i') { gotoCase = 43; continue; }; case 69: yych = this._charAt(++cursor); if (yych == 'P') { gotoCase = 70; continue; }; if (yych != 'p') { gotoCase = 43; continue; }; case 70: yych = this._charAt(++cursor); if (yych == 'T') { gotoCase = 71; continue; }; if (yych != 't') { gotoCase = 43; continue; }; case 71: ++cursor; this.setLexCondition(this._lexConditions.TAG); { if (this._condition.parseCondition & this._parseConditions.SCRIPT) { this.setLexCondition(this._lexConditions.INITIAL); this.tokenType = null; return cursor; } this.tokenType = "html-tag"; this._condition.parseCondition = this._parseConditions.SCRIPT; this._setExpectingAttribute(); return cursor; } case 73: yych = this._charAt(++cursor); if (yych <= 'T') { if (yych == 'C') { gotoCase = 75; continue; }; if (yych <= 'S') { gotoCase = 43; continue; }; } else { if (yych <= 'c') { if (yych <= 'b') { gotoCase = 43; continue; }; { gotoCase = 75; continue; }; } else { if (yych != 't') { gotoCase = 43; continue; }; } } yych = this._charAt(++cursor); if (yych == 'Y') { gotoCase = 81; continue; }; if (yych == 'y') { gotoCase = 81; continue; }; { gotoCase = 43; continue; }; case 75: yych = this._charAt(++cursor); if (yych == 'R') { gotoCase = 76; continue; }; if (yych != 'r') { gotoCase = 43; continue; }; case 76: yych = this._charAt(++cursor); if (yych == 'I') { gotoCase = 77; continue; }; if (yych != 'i') { gotoCase = 43; continue; }; case 77: yych = this._charAt(++cursor); if (yych == 'P') { gotoCase = 78; continue; }; if (yych != 'p') { gotoCase = 43; continue; }; case 78: yych = this._charAt(++cursor); if (yych == 'T') { gotoCase = 79; continue; }; if (yych != 't') { gotoCase = 43; continue; }; case 79: ++cursor; this.setLexCondition(this._lexConditions.TAG); { this.tokenType = "html-tag"; this._condition.parseCondition = this._parseConditions.INITIAL; this.scriptEnded(cursor - 8); return cursor; } case 81: yych = this._charAt(++cursor); if (yych == 'L') { gotoCase = 82; continue; }; if (yych != 'l') { gotoCase = 43; continue; }; case 82: yych = this._charAt(++cursor); if (yych == 'E') { gotoCase = 83; continue; }; if (yych != 'e') { gotoCase = 43; continue; }; case 83: ++cursor; this.setLexCondition(this._lexConditions.TAG); { this.tokenType = "html-tag"; this._condition.parseCondition = this._parseConditions.INITIAL; this.styleSheetEnded(cursor - 7); return cursor; } case this.case_SSTRING: yych = this._charAt(cursor); if (yych <= '\f') { if (yych == '\n') { gotoCase = 89; continue; }; { gotoCase = 88; continue; }; } else { if (yych <= '\r') { gotoCase = 89; continue; }; if (yych == '\'') { gotoCase = 91; continue; }; { gotoCase = 88; continue; }; } case 87: { return this._stringToken(cursor); } case 88: yych = this._charAt(++cursor); { gotoCase = 95; continue; }; case 89: ++cursor; { this.tokenType = null; return cursor; } case 91: ++cursor; case 92: this.setLexCondition(this._lexConditions.TAG); { return this._stringToken(cursor, true); } case 93: yych = this._charAt(++cursor); { gotoCase = 92; continue; }; case 94: ++cursor; yych = this._charAt(cursor); case 95: if (yych <= '\f') { if (yych == '\n') { gotoCase = 87; continue; }; { gotoCase = 94; continue; }; } else { if (yych <= '\r') { gotoCase = 87; continue; }; if (yych == '\'') { gotoCase = 93; continue; }; { gotoCase = 94; continue; }; } case this.case_TAG: yych = this._charAt(cursor); if (yych <= '&') { if (yych <= '\r') { if (yych == '\n') { gotoCase = 100; continue; }; if (yych >= '\r') { gotoCase = 100; continue; }; } else { if (yych <= ' ') { if (yych >= ' ') { gotoCase = 100; continue; }; } else { if (yych == '"') { gotoCase = 102; continue; }; } } } else { if (yych <= '>') { if (yych <= ';') { if (yych <= '\'') { gotoCase = 103; continue; }; } else { if (yych <= '<') { gotoCase = 100; continue; }; if (yych <= '=') { gotoCase = 104; continue; }; { gotoCase = 106; continue; }; } } else { if (yych <= '[') { if (yych >= '[') { gotoCase = 100; continue; }; } else { if (yych == ']') { gotoCase = 100; continue; }; } } } ++cursor; yych = this._charAt(cursor); { gotoCase = 119; continue; }; case 99: { if (this._condition.parseCondition === this._parseConditions.SCRIPT || this._condition.parseCondition === this._parseConditions.STYLE) { this.tokenType = null; return cursor; } if (this._condition.parseCondition === this._parseConditions.INITIAL) { this.tokenType = "html-tag"; this._setExpectingAttribute(); var token = this._line.substring(cursorOnEnter, cursor); if (token === "a") this._condition.parseCondition |= this._parseConditions.A_NODE; else if (this._condition.parseCondition & this._parseConditions.A_NODE) this._condition.parseCondition ^= this._parseConditions.A_NODE; } else if (this._isExpectingAttribute()) { var token = this._line.substring(cursorOnEnter, cursor); if (token === "href" || token === "src") this._condition.parseCondition |= this._parseConditions.LINKIFY; else if (this._condition.parseCondition |= this._parseConditions.LINKIFY) this._condition.parseCondition ^= this._parseConditions.LINKIFY; this.tokenType = "html-attribute-name"; } else if (this._isExpectingAttributeValue()) this.tokenType = this._attrValueTokenType(); else this.tokenType = null; return cursor; } case 100: ++cursor; { this.tokenType = null; return cursor; } case 102: yyaccept = 0; yych = this._charAt(YYMARKER = ++cursor); { gotoCase = 115; continue; }; case 103: yyaccept = 0; yych = this._charAt(YYMARKER = ++cursor); { gotoCase = 109; continue; }; case 104: ++cursor; { if (this._isExpectingAttribute()) this._setExpectingAttributeValue(); this.tokenType = null; return cursor; } case 106: ++cursor; this.setLexCondition(this._lexConditions.INITIAL); { this.tokenType = "html-tag"; if (this._condition.parseCondition & this._parseConditions.SCRIPT) { this.scriptStarted(cursor); return cursor; } if (this._condition.parseCondition & this._parseConditions.STYLE) { this.styleSheetStarted(cursor); return cursor; } this._condition.parseCondition = this._parseConditions.INITIAL; return cursor; } case 108: ++cursor; yych = this._charAt(cursor); case 109: if (yych <= '\f') { if (yych != '\n') { gotoCase = 108; continue; }; } else { if (yych <= '\r') { gotoCase = 110; continue; }; if (yych == '\'') { gotoCase = 112; continue; }; { gotoCase = 108; continue; }; } case 110: ++cursor; this.setLexCondition(this._lexConditions.SSTRING); { return this._stringToken(cursor); } case 112: ++cursor; { return this._stringToken(cursor, true); } case 114: ++cursor; yych = this._charAt(cursor); case 115: if (yych <= '\f') { if (yych != '\n') { gotoCase = 114; continue; }; } else { if (yych <= '\r') { gotoCase = 116; continue; }; if (yych == '"') { gotoCase = 112; continue; }; { gotoCase = 114; continue; }; } case 116: ++cursor; this.setLexCondition(this._lexConditions.DSTRING); { return this._stringToken(cursor); } case 118: ++cursor; yych = this._charAt(cursor); case 119: if (yych <= '"') { if (yych <= '\r') { if (yych == '\n') { gotoCase = 99; continue; }; if (yych <= '\f') { gotoCase = 118; continue; }; { gotoCase = 99; continue; }; } else { if (yych == ' ') { gotoCase = 99; continue; }; if (yych <= '!') { gotoCase = 118; continue; }; { gotoCase = 99; continue; }; } } else { if (yych <= '>') { if (yych == '\'') { gotoCase = 99; continue; }; if (yych <= ';') { gotoCase = 118; continue; }; { gotoCase = 99; continue; }; } else { if (yych <= '[') { if (yych <= 'Z') { gotoCase = 118; continue; }; { gotoCase = 99; continue; }; } else { if (yych == ']') { gotoCase = 99; continue; }; { gotoCase = 118; continue; }; } } } } } }, __proto__: WebInspector.SourceTokenizer.prototype } WebInspector.SourceJavaScriptTokenizer = function() { WebInspector.SourceTokenizer.call(this); this._lexConditions = { DIV: 0, NODIV: 1, COMMENT: 2, DSTRING: 3, SSTRING: 4, REGEX: 5 }; this.case_DIV = 1000; this.case_NODIV = 1001; this.case_COMMENT = 1002; this.case_DSTRING = 1003; this.case_SSTRING = 1004; this.case_REGEX = 1005; this.condition = this.createInitialCondition(); } WebInspector.SourceJavaScriptTokenizer.Keywords = [ "null", "true", "false", "break", "case", "catch", "const", "default", "finally", "for", "instanceof", "new", "var", "continue", "function", "return", "void", "delete", "if", "this", "do", "while", "else", "in", "switch", "throw", "try", "typeof", "debugger", "class", "enum", "export", "extends", "import", "super", "get", "set", "with" ].keySet(); WebInspector.SourceJavaScriptTokenizer.prototype = { createInitialCondition: function() { return { lexCondition: this._lexConditions.NODIV }; }, nextToken: function(cursor) { var cursorOnEnter = cursor; var gotoCase = 1; var YYMARKER; while (1) { switch (gotoCase) { case 1: var yych; var yyaccept = 0; if (this.getLexCondition() < 3) { if (this.getLexCondition() < 1) { { gotoCase = this.case_DIV; continue; }; } else { if (this.getLexCondition() < 2) { { gotoCase = this.case_NODIV; continue; }; } else { { gotoCase = this.case_COMMENT; continue; }; } } } else { if (this.getLexCondition() < 4) { { gotoCase = this.case_DSTRING; continue; }; } else { if (this.getLexCondition() < 5) { { gotoCase = this.case_SSTRING; continue; }; } else { { gotoCase = this.case_REGEX; continue; }; } } } case this.case_COMMENT: yych = this._charAt(cursor); if (yych <= '\f') { if (yych == '\n') { gotoCase = 4; continue; }; { gotoCase = 3; continue; }; } else { if (yych <= '\r') { gotoCase = 4; continue; }; if (yych == '*') { gotoCase = 6; continue; }; { gotoCase = 3; continue; }; } case 2: { this.tokenType = "javascript-comment"; return cursor; } case 3: yyaccept = 0; yych = this._charAt(YYMARKER = ++cursor); { gotoCase = 12; continue; }; case 4: ++cursor; { this.tokenType = null; return cursor; } case 6: yyaccept = 1; yych = this._charAt(YYMARKER = ++cursor); if (yych == '*') { gotoCase = 9; continue; }; if (yych != '/') { gotoCase = 11; continue; }; case 7: ++cursor; this.setLexCondition(this._lexConditions.NODIV); { this.tokenType = "javascript-comment"; return cursor; } case 9: ++cursor; yych = this._charAt(cursor); if (yych == '*') { gotoCase = 9; continue; }; if (yych == '/') { gotoCase = 7; continue; }; case 11: yyaccept = 0; YYMARKER = ++cursor; yych = this._charAt(cursor); case 12: if (yych <= '\f') { if (yych == '\n') { gotoCase = 2; continue; }; { gotoCase = 11; continue; }; } else { if (yych <= '\r') { gotoCase = 2; continue; }; if (yych == '*') { gotoCase = 9; continue; }; { gotoCase = 11; continue; }; } case this.case_DIV: yych = this._charAt(cursor); if (yych <= '9') { if (yych <= '(') { if (yych <= '#') { if (yych <= ' ') { gotoCase = 15; continue; }; if (yych <= '!') { gotoCase = 17; continue; }; if (yych <= '"') { gotoCase = 19; continue; }; } else { if (yych <= '%') { if (yych <= '$') { gotoCase = 20; continue; }; { gotoCase = 22; continue; }; } else { if (yych <= '&') { gotoCase = 23; continue; }; if (yych <= '\'') { gotoCase = 24; continue; }; { gotoCase = 25; continue; }; } } } else { if (yych <= ',') { if (yych <= ')') { gotoCase = 26; continue; }; if (yych <= '*') { gotoCase = 28; continue; }; if (yych <= '+') { gotoCase = 29; continue; }; { gotoCase = 25; continue; }; } else { if (yych <= '.') { if (yych <= '-') { gotoCase = 30; continue; }; { gotoCase = 31; continue; }; } else { if (yych <= '/') { gotoCase = 32; continue; }; if (yych <= '0') { gotoCase = 34; continue; }; { gotoCase = 36; continue; }; } } } } else { if (yych <= '\\') { if (yych <= '>') { if (yych <= ';') { gotoCase = 25; continue; }; if (yych <= '<') { gotoCase = 37; continue; }; if (yych <= '=') { gotoCase = 38; continue; }; { gotoCase = 39; continue; }; } else { if (yych <= '@') { if (yych <= '?') { gotoCase = 25; continue; }; } else { if (yych <= 'Z') { gotoCase = 20; continue; }; if (yych <= '[') { gotoCase = 25; continue; }; { gotoCase = 40; continue; }; } } } else { if (yych <= 'z') { if (yych <= '^') { if (yych <= ']') { gotoCase = 25; continue; }; { gotoCase = 41; continue; }; } else { if (yych != '`') { gotoCase = 20; continue; }; } } else { if (yych <= '|') { if (yych <= '{') { gotoCase = 25; continue; }; { gotoCase = 42; continue; }; } else { if (yych <= '~') { gotoCase = 25; continue; }; if (yych >= 0x80) { gotoCase = 20; continue; }; } } } } case 15: ++cursor; case 16: { this.tokenType = null; return cursor; } case 17: ++cursor; if ((yych = this._charAt(cursor)) == '=') { gotoCase = 115; continue; }; case 18: this.setLexCondition(this._lexConditions.NODIV); { var token = this._line.charAt(cursorOnEnter); if (token === "{") this.tokenType = "block-start"; else if (token === "}") this.tokenType = "block-end"; else this.tokenType = null; return cursor; } case 19: yyaccept = 0; yych = this._charAt(YYMARKER = ++cursor); if (yych == '\n') { gotoCase = 16; continue; }; if (yych == '\r') { gotoCase = 16; continue; }; { gotoCase = 107; continue; }; case 20: yyaccept = 1; yych = this._charAt(YYMARKER = ++cursor); { gotoCase = 50; continue; }; case 21: { var token = this._line.substring(cursorOnEnter, cursor); if (WebInspector.SourceJavaScriptTokenizer.Keywords[token] === true && token !== "__proto__") this.tokenType = "javascript-keyword"; else this.tokenType = "javascript-ident"; return cursor; } case 22: yych = this._charAt(++cursor); if (yych == '=') { gotoCase = 43; continue; }; { gotoCase = 18; continue; }; case 23: yych = this._charAt(++cursor); if (yych == '&') { gotoCase = 43; continue; }; if (yych == '=') { gotoCase = 43; continue; }; { gotoCase = 18; continue; }; case 24: yyaccept = 0; yych = this._charAt(YYMARKER = ++cursor); if (yych == '\n') { gotoCase = 16; continue; }; if (yych == '\r') { gotoCase = 16; continue; }; { gotoCase = 96; continue; }; case 25: yych = this._charAt(++cursor); { gotoCase = 18; continue; }; case 26: ++cursor; { this.tokenType = null; return cursor; } case 28: yych = this._charAt(++cursor); if (yych == '=') { gotoCase = 43; continue; }; { gotoCase = 18; continue; }; case 29: yych = this._charAt(++cursor); if (yych == '+') { gotoCase = 43; continue; }; if (yych == '=') { gotoCase = 43; continue; }; { gotoCase = 18; continue; }; case 30: yych = this._charAt(++cursor); if (yych == '-') { gotoCase = 43; continue; }; if (yych == '=') { gotoCase = 43; continue; }; { gotoCase = 18; continue; }; case 31: yych = this._charAt(++cursor); if (yych <= '/') { gotoCase = 18; continue; }; if (yych <= '9') { gotoCase = 89; continue; }; { gotoCase = 18; continue; }; case 32: yyaccept = 2; yych = this._charAt(YYMARKER = ++cursor); if (yych <= '.') { if (yych == '*') { gotoCase = 78; continue; }; } else { if (yych <= '/') { gotoCase = 80; continue; }; if (yych == '=') { gotoCase = 77; continue; }; } case 33: this.setLexCondition(this._lexConditions.NODIV); { this.tokenType = null; return cursor; } case 34: yyaccept = 3; yych = this._charAt(YYMARKER = ++cursor); if (yych <= 'E') { if (yych <= '/') { if (yych == '.') { gotoCase = 63; continue; }; } else { if (yych <= '7') { gotoCase = 72; continue; }; if (yych >= 'E') { gotoCase = 62; continue; }; } } else { if (yych <= 'd') { if (yych == 'X') { gotoCase = 74; continue; }; } else { if (yych <= 'e') { gotoCase = 62; continue; }; if (yych == 'x') { gotoCase = 74; continue; }; } } case 35: { this.tokenType = "javascript-number"; return cursor; } case 36: yyaccept = 3; yych = this._charAt(YYMARKER = ++cursor); if (yych <= '9') { if (yych == '.') { gotoCase = 63; continue; }; if (yych <= '/') { gotoCase = 35; continue; }; { gotoCase = 60; continue; }; } else { if (yych <= 'E') { if (yych <= 'D') { gotoCase = 35; continue; }; { gotoCase = 62; continue; }; } else { if (yych == 'e') { gotoCase = 62; continue; }; { gotoCase = 35; continue; }; } } case 37: yych = this._charAt(++cursor); if (yych <= ';') { gotoCase = 18; continue; }; if (yych <= '<') { gotoCase = 59; continue; }; if (yych <= '=') { gotoCase = 43; continue; }; { gotoCase = 18; continue; }; case 38: yych = this._charAt(++cursor); if (yych == '=') { gotoCase = 58; continue; }; { gotoCase = 18; continue; }; case 39: yych = this._charAt(++cursor); if (yych <= '<') { gotoCase = 18; continue; }; if (yych <= '=') { gotoCase = 43; continue; }; if (yych <= '>') { gotoCase = 56; continue; }; { gotoCase = 18; continue; }; case 40: yyaccept = 0; yych = this._charAt(YYMARKER = ++cursor); if (yych == 'u') { gotoCase = 44; continue; }; { gotoCase = 16; continue; }; case 41: yych = this._charAt(++cursor); if (yych == '=') { gotoCase = 43; continue; }; { gotoCase = 18; continue; }; case 42: yych = this._charAt(++cursor); if (yych == '=') { gotoCase = 43; continue; }; if (yych != '|') { gotoCase = 18; continue; }; case 43: yych = this._charAt(++cursor); { gotoCase = 18; continue; }; case 44: yych = this._charAt(++cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 45; continue; }; if (yych <= '9') { gotoCase = 46; continue; }; } else { if (yych <= 'F') { gotoCase = 46; continue; }; if (yych <= '`') { gotoCase = 45; continue; }; if (yych <= 'f') { gotoCase = 46; continue; }; } case 45: cursor = YYMARKER; if (yyaccept <= 1) { if (yyaccept <= 0) { { gotoCase = 16; continue; }; } else { { gotoCase = 21; continue; }; } } else { if (yyaccept <= 2) { { gotoCase = 33; continue; }; } else { { gotoCase = 35; continue; }; } } case 46: yych = this._charAt(++cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 45; continue; }; if (yych >= ':') { gotoCase = 45; continue; }; } else { if (yych <= 'F') { gotoCase = 47; continue; }; if (yych <= '`') { gotoCase = 45; continue; }; if (yych >= 'g') { gotoCase = 45; continue; }; } case 47: yych = this._charAt(++cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 45; continue; }; if (yych >= ':') { gotoCase = 45; continue; }; } else { if (yych <= 'F') { gotoCase = 48; continue; }; if (yych <= '`') { gotoCase = 45; continue; }; if (yych >= 'g') { gotoCase = 45; continue; }; } case 48: yych = this._charAt(++cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 45; continue; }; if (yych >= ':') { gotoCase = 45; continue; }; } else { if (yych <= 'F') { gotoCase = 49; continue; }; if (yych <= '`') { gotoCase = 45; continue; }; if (yych >= 'g') { gotoCase = 45; continue; }; } case 49: yyaccept = 1; YYMARKER = ++cursor; yych = this._charAt(cursor); case 50: if (yych <= '[') { if (yych <= '/') { if (yych == '$') { gotoCase = 49; continue; }; { gotoCase = 21; continue; }; } else { if (yych <= '9') { gotoCase = 49; continue; }; if (yych <= '@') { gotoCase = 21; continue; }; if (yych <= 'Z') { gotoCase = 49; continue; }; { gotoCase = 21; continue; }; } } else { if (yych <= '_') { if (yych <= '\\') { gotoCase = 51; continue; }; if (yych <= '^') { gotoCase = 21; continue; }; { gotoCase = 49; continue; }; } else { if (yych <= '`') { gotoCase = 21; continue; }; if (yych <= 'z') { gotoCase = 49; continue; }; if (yych <= String.fromCharCode(0x7F)) { gotoCase = 21; continue; }; { gotoCase = 49; continue; }; } } case 51: ++cursor; yych = this._charAt(cursor); if (yych != 'u') { gotoCase = 45; continue; }; ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 45; continue; }; if (yych >= ':') { gotoCase = 45; continue; }; } else { if (yych <= 'F') { gotoCase = 53; continue; }; if (yych <= '`') { gotoCase = 45; continue; }; if (yych >= 'g') { gotoCase = 45; continue; }; } case 53: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 45; continue; }; if (yych >= ':') { gotoCase = 45; continue; }; } else { if (yych <= 'F') { gotoCase = 54; continue; }; if (yych <= '`') { gotoCase = 45; continue; }; if (yych >= 'g') { gotoCase = 45; continue; }; } case 54: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 45; continue; }; if (yych >= ':') { gotoCase = 45; continue; }; } else { if (yych <= 'F') { gotoCase = 55; continue; }; if (yych <= '`') { gotoCase = 45; continue; }; if (yych >= 'g') { gotoCase = 45; continue; }; } case 55: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 45; continue; }; if (yych <= '9') { gotoCase = 49; continue; }; { gotoCase = 45; continue; }; } else { if (yych <= 'F') { gotoCase = 49; continue; }; if (yych <= '`') { gotoCase = 45; continue; }; if (yych <= 'f') { gotoCase = 49; continue; }; { gotoCase = 45; continue; }; } case 56: yych = this._charAt(++cursor); if (yych <= '<') { gotoCase = 18; continue; }; if (yych <= '=') { gotoCase = 43; continue; }; if (yych >= '?') { gotoCase = 18; continue; }; yych = this._charAt(++cursor); if (yych == '=') { gotoCase = 43; continue; }; { gotoCase = 18; continue; }; case 58: yych = this._charAt(++cursor); if (yych == '=') { gotoCase = 43; continue; }; { gotoCase = 18; continue; }; case 59: yych = this._charAt(++cursor); if (yych == '=') { gotoCase = 43; continue; }; { gotoCase = 18; continue; }; case 60: yyaccept = 3; YYMARKER = ++cursor; yych = this._charAt(cursor); if (yych <= '9') { if (yych == '.') { gotoCase = 63; continue; }; if (yych <= '/') { gotoCase = 35; continue; }; { gotoCase = 60; continue; }; } else { if (yych <= 'E') { if (yych <= 'D') { gotoCase = 35; continue; }; } else { if (yych != 'e') { gotoCase = 35; continue; }; } } case 62: yych = this._charAt(++cursor); if (yych <= ',') { if (yych == '+') { gotoCase = 69; continue; }; { gotoCase = 45; continue; }; } else { if (yych <= '-') { gotoCase = 69; continue; }; if (yych <= '/') { gotoCase = 45; continue; }; if (yych <= '9') { gotoCase = 70; continue; }; { gotoCase = 45; continue; }; } case 63: yyaccept = 3; YYMARKER = ++cursor; yych = this._charAt(cursor); if (yych <= 'D') { if (yych <= '/') { gotoCase = 35; continue; }; if (yych <= '9') { gotoCase = 63; continue; }; { gotoCase = 35; continue; }; } else { if (yych <= 'E') { gotoCase = 65; continue; }; if (yych != 'e') { gotoCase = 35; continue; }; } case 65: yych = this._charAt(++cursor); if (yych <= ',') { if (yych != '+') { gotoCase = 45; continue; }; } else { if (yych <= '-') { gotoCase = 66; continue; }; if (yych <= '/') { gotoCase = 45; continue; }; if (yych <= '9') { gotoCase = 67; continue; }; { gotoCase = 45; continue; }; } case 66: yych = this._charAt(++cursor); if (yych <= '/') { gotoCase = 45; continue; }; if (yych >= ':') { gotoCase = 45; continue; }; case 67: ++cursor; yych = this._charAt(cursor); if (yych <= '/') { gotoCase = 35; continue; }; if (yych <= '9') { gotoCase = 67; continue; }; { gotoCase = 35; continue; }; case 69: yych = this._charAt(++cursor); if (yych <= '/') { gotoCase = 45; continue; }; if (yych >= ':') { gotoCase = 45; continue; }; case 70: ++cursor; yych = this._charAt(cursor); if (yych <= '/') { gotoCase = 35; continue; }; if (yych <= '9') { gotoCase = 70; continue; }; { gotoCase = 35; continue; }; case 72: ++cursor; yych = this._charAt(cursor); if (yych <= '/') { gotoCase = 35; continue; }; if (yych <= '7') { gotoCase = 72; continue; }; { gotoCase = 35; continue; }; case 74: yych = this._charAt(++cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 45; continue; }; if (yych >= ':') { gotoCase = 45; continue; }; } else { if (yych <= 'F') { gotoCase = 75; continue; }; if (yych <= '`') { gotoCase = 45; continue; }; if (yych >= 'g') { gotoCase = 45; continue; }; } case 75: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 35; continue; }; if (yych <= '9') { gotoCase = 75; continue; }; { gotoCase = 35; continue; }; } else { if (yych <= 'F') { gotoCase = 75; continue; }; if (yych <= '`') { gotoCase = 35; continue; }; if (yych <= 'f') { gotoCase = 75; continue; }; { gotoCase = 35; continue; }; } case 77: yych = this._charAt(++cursor); { gotoCase = 33; continue; }; case 78: ++cursor; yych = this._charAt(cursor); if (yych <= '\f') { if (yych == '\n') { gotoCase = 85; continue; }; { gotoCase = 78; continue; }; } else { if (yych <= '\r') { gotoCase = 85; continue; }; if (yych == '*') { gotoCase = 83; continue; }; { gotoCase = 78; continue; }; } case 80: ++cursor; yych = this._charAt(cursor); if (yych == '\n') { gotoCase = 82; continue; }; if (yych != '\r') { gotoCase = 80; continue; }; case 82: { this.tokenType = "javascript-comment"; return cursor; } case 83: ++cursor; yych = this._charAt(cursor); if (yych == '*') { gotoCase = 83; continue; }; if (yych == '/') { gotoCase = 87; continue; }; { gotoCase = 78; continue; }; case 85: ++cursor; this.setLexCondition(this._lexConditions.COMMENT); { this.tokenType = "javascript-comment"; return cursor; } case 87: ++cursor; { this.tokenType = "javascript-comment"; return cursor; } case 89: yyaccept = 3; YYMARKER = ++cursor; yych = this._charAt(cursor); if (yych <= 'D') { if (yych <= '/') { gotoCase = 35; continue; }; if (yych <= '9') { gotoCase = 89; continue; }; { gotoCase = 35; continue; }; } else { if (yych <= 'E') { gotoCase = 91; continue; }; if (yych != 'e') { gotoCase = 35; continue; }; } case 91: yych = this._charAt(++cursor); if (yych <= ',') { if (yych != '+') { gotoCase = 45; continue; }; } else { if (yych <= '-') { gotoCase = 92; continue; }; if (yych <= '/') { gotoCase = 45; continue; }; if (yych <= '9') { gotoCase = 93; continue; }; { gotoCase = 45; continue; }; } case 92: yych = this._charAt(++cursor); if (yych <= '/') { gotoCase = 45; continue; }; if (yych >= ':') { gotoCase = 45; continue; }; case 93: ++cursor; yych = this._charAt(cursor); if (yych <= '/') { gotoCase = 35; continue; }; if (yych <= '9') { gotoCase = 93; continue; }; { gotoCase = 35; continue; }; case 95: ++cursor; yych = this._charAt(cursor); case 96: if (yych <= '\r') { if (yych == '\n') { gotoCase = 45; continue; }; if (yych <= '\f') { gotoCase = 95; continue; }; { gotoCase = 45; continue; }; } else { if (yych <= '\'') { if (yych <= '&') { gotoCase = 95; continue; }; { gotoCase = 98; continue; }; } else { if (yych != '\\') { gotoCase = 95; continue; }; } } ++cursor; yych = this._charAt(cursor); if (yych <= 'a') { if (yych <= '!') { if (yych <= '\n') { if (yych <= '\t') { gotoCase = 45; continue; }; { gotoCase = 101; continue; }; } else { if (yych == '\r') { gotoCase = 101; continue; }; { gotoCase = 45; continue; }; } } else { if (yych <= '\'') { if (yych <= '"') { gotoCase = 95; continue; }; if (yych <= '&') { gotoCase = 45; continue; }; { gotoCase = 95; continue; }; } else { if (yych == '\\') { gotoCase = 95; continue; }; { gotoCase = 45; continue; }; } } } else { if (yych <= 'q') { if (yych <= 'f') { if (yych <= 'b') { gotoCase = 95; continue; }; if (yych <= 'e') { gotoCase = 45; continue; }; { gotoCase = 95; continue; }; } else { if (yych == 'n') { gotoCase = 95; continue; }; { gotoCase = 45; continue; }; } } else { if (yych <= 't') { if (yych == 's') { gotoCase = 45; continue; }; { gotoCase = 95; continue; }; } else { if (yych <= 'u') { gotoCase = 100; continue; }; if (yych <= 'v') { gotoCase = 95; continue; }; { gotoCase = 45; continue; }; } } } case 98: ++cursor; { this.tokenType = "javascript-string"; return cursor; } case 100: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 45; continue; }; if (yych <= '9') { gotoCase = 103; continue; }; { gotoCase = 45; continue; }; } else { if (yych <= 'F') { gotoCase = 103; continue; }; if (yych <= '`') { gotoCase = 45; continue; }; if (yych <= 'f') { gotoCase = 103; continue; }; { gotoCase = 45; continue; }; } case 101: ++cursor; this.setLexCondition(this._lexConditions.SSTRING); { this.tokenType = "javascript-string"; return cursor; } case 103: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 45; continue; }; if (yych >= ':') { gotoCase = 45; continue; }; } else { if (yych <= 'F') { gotoCase = 104; continue; }; if (yych <= '`') { gotoCase = 45; continue; }; if (yych >= 'g') { gotoCase = 45; continue; }; } case 104: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 45; continue; }; if (yych >= ':') { gotoCase = 45; continue; }; } else { if (yych <= 'F') { gotoCase = 105; continue; }; if (yych <= '`') { gotoCase = 45; continue; }; if (yych >= 'g') { gotoCase = 45; continue; }; } case 105: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 45; continue; }; if (yych <= '9') { gotoCase = 95; continue; }; { gotoCase = 45; continue; }; } else { if (yych <= 'F') { gotoCase = 95; continue; }; if (yych <= '`') { gotoCase = 45; continue; }; if (yych <= 'f') { gotoCase = 95; continue; }; { gotoCase = 45; continue; }; } case 106: ++cursor; yych = this._charAt(cursor); case 107: if (yych <= '\r') { if (yych == '\n') { gotoCase = 45; continue; }; if (yych <= '\f') { gotoCase = 106; continue; }; { gotoCase = 45; continue; }; } else { if (yych <= '"') { if (yych <= '!') { gotoCase = 106; continue; }; { gotoCase = 98; continue; }; } else { if (yych != '\\') { gotoCase = 106; continue; }; } } ++cursor; yych = this._charAt(cursor); if (yych <= 'a') { if (yych <= '!') { if (yych <= '\n') { if (yych <= '\t') { gotoCase = 45; continue; }; { gotoCase = 110; continue; }; } else { if (yych == '\r') { gotoCase = 110; continue; }; { gotoCase = 45; continue; }; } } else { if (yych <= '\'') { if (yych <= '"') { gotoCase = 106; continue; }; if (yych <= '&') { gotoCase = 45; continue; }; { gotoCase = 106; continue; }; } else { if (yych == '\\') { gotoCase = 106; continue; }; { gotoCase = 45; continue; }; } } } else { if (yych <= 'q') { if (yych <= 'f') { if (yych <= 'b') { gotoCase = 106; continue; }; if (yych <= 'e') { gotoCase = 45; continue; }; { gotoCase = 106; continue; }; } else { if (yych == 'n') { gotoCase = 106; continue; }; { gotoCase = 45; continue; }; } } else { if (yych <= 't') { if (yych == 's') { gotoCase = 45; continue; }; { gotoCase = 106; continue; }; } else { if (yych <= 'u') { gotoCase = 109; continue; }; if (yych <= 'v') { gotoCase = 106; continue; }; { gotoCase = 45; continue; }; } } } case 109: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 45; continue; }; if (yych <= '9') { gotoCase = 112; continue; }; { gotoCase = 45; continue; }; } else { if (yych <= 'F') { gotoCase = 112; continue; }; if (yych <= '`') { gotoCase = 45; continue; }; if (yych <= 'f') { gotoCase = 112; continue; }; { gotoCase = 45; continue; }; } case 110: ++cursor; this.setLexCondition(this._lexConditions.DSTRING); { this.tokenType = "javascript-string"; return cursor; } case 112: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 45; continue; }; if (yych >= ':') { gotoCase = 45; continue; }; } else { if (yych <= 'F') { gotoCase = 113; continue; }; if (yych <= '`') { gotoCase = 45; continue; }; if (yych >= 'g') { gotoCase = 45; continue; }; } case 113: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 45; continue; }; if (yych >= ':') { gotoCase = 45; continue; }; } else { if (yych <= 'F') { gotoCase = 114; continue; }; if (yych <= '`') { gotoCase = 45; continue; }; if (yych >= 'g') { gotoCase = 45; continue; }; } case 114: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 45; continue; }; if (yych <= '9') { gotoCase = 106; continue; }; { gotoCase = 45; continue; }; } else { if (yych <= 'F') { gotoCase = 106; continue; }; if (yych <= '`') { gotoCase = 45; continue; }; if (yych <= 'f') { gotoCase = 106; continue; }; { gotoCase = 45; continue; }; } case 115: ++cursor; if ((yych = this._charAt(cursor)) == '=') { gotoCase = 43; continue; }; { gotoCase = 18; continue; }; case this.case_DSTRING: yych = this._charAt(cursor); if (yych <= '\r') { if (yych == '\n') { gotoCase = 120; continue; }; if (yych <= '\f') { gotoCase = 119; continue; }; { gotoCase = 120; continue; }; } else { if (yych <= '"') { if (yych <= '!') { gotoCase = 119; continue; }; { gotoCase = 122; continue; }; } else { if (yych == '\\') { gotoCase = 124; continue; }; { gotoCase = 119; continue; }; } } case 118: { this.tokenType = "javascript-string"; return cursor; } case 119: yyaccept = 0; yych = this._charAt(YYMARKER = ++cursor); { gotoCase = 126; continue; }; case 120: ++cursor; case 121: { this.tokenType = null; return cursor; } case 122: ++cursor; case 123: this.setLexCondition(this._lexConditions.NODIV); { this.tokenType = "javascript-string"; return cursor; } case 124: yyaccept = 1; yych = this._charAt(YYMARKER = ++cursor); if (yych <= 'e') { if (yych <= '\'') { if (yych == '"') { gotoCase = 125; continue; }; if (yych <= '&') { gotoCase = 121; continue; }; } else { if (yych <= '\\') { if (yych <= '[') { gotoCase = 121; continue; }; } else { if (yych != 'b') { gotoCase = 121; continue; }; } } } else { if (yych <= 'r') { if (yych <= 'm') { if (yych >= 'g') { gotoCase = 121; continue; }; } else { if (yych <= 'n') { gotoCase = 125; continue; }; if (yych <= 'q') { gotoCase = 121; continue; }; } } else { if (yych <= 't') { if (yych <= 's') { gotoCase = 121; continue; }; } else { if (yych <= 'u') { gotoCase = 127; continue; }; if (yych >= 'w') { gotoCase = 121; continue; }; } } } case 125: yyaccept = 0; YYMARKER = ++cursor; yych = this._charAt(cursor); case 126: if (yych <= '\r') { if (yych == '\n') { gotoCase = 118; continue; }; if (yych <= '\f') { gotoCase = 125; continue; }; { gotoCase = 118; continue; }; } else { if (yych <= '"') { if (yych <= '!') { gotoCase = 125; continue; }; { gotoCase = 133; continue; }; } else { if (yych == '\\') { gotoCase = 132; continue; }; { gotoCase = 125; continue; }; } } case 127: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 128; continue; }; if (yych <= '9') { gotoCase = 129; continue; }; } else { if (yych <= 'F') { gotoCase = 129; continue; }; if (yych <= '`') { gotoCase = 128; continue; }; if (yych <= 'f') { gotoCase = 129; continue; }; } case 128: cursor = YYMARKER; if (yyaccept <= 0) { { gotoCase = 118; continue; }; } else { { gotoCase = 121; continue; }; } case 129: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 128; continue; }; if (yych >= ':') { gotoCase = 128; continue; }; } else { if (yych <= 'F') { gotoCase = 130; continue; }; if (yych <= '`') { gotoCase = 128; continue; }; if (yych >= 'g') { gotoCase = 128; continue; }; } case 130: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 128; continue; }; if (yych >= ':') { gotoCase = 128; continue; }; } else { if (yych <= 'F') { gotoCase = 131; continue; }; if (yych <= '`') { gotoCase = 128; continue; }; if (yych >= 'g') { gotoCase = 128; continue; }; } case 131: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 128; continue; }; if (yych <= '9') { gotoCase = 125; continue; }; { gotoCase = 128; continue; }; } else { if (yych <= 'F') { gotoCase = 125; continue; }; if (yych <= '`') { gotoCase = 128; continue; }; if (yych <= 'f') { gotoCase = 125; continue; }; { gotoCase = 128; continue; }; } case 132: ++cursor; yych = this._charAt(cursor); if (yych <= 'e') { if (yych <= '\'') { if (yych == '"') { gotoCase = 125; continue; }; if (yych <= '&') { gotoCase = 128; continue; }; { gotoCase = 125; continue; }; } else { if (yych <= '\\') { if (yych <= '[') { gotoCase = 128; continue; }; { gotoCase = 125; continue; }; } else { if (yych == 'b') { gotoCase = 125; continue; }; { gotoCase = 128; continue; }; } } } else { if (yych <= 'r') { if (yych <= 'm') { if (yych <= 'f') { gotoCase = 125; continue; }; { gotoCase = 128; continue; }; } else { if (yych <= 'n') { gotoCase = 125; continue; }; if (yych <= 'q') { gotoCase = 128; continue; }; { gotoCase = 125; continue; }; } } else { if (yych <= 't') { if (yych <= 's') { gotoCase = 128; continue; }; { gotoCase = 125; continue; }; } else { if (yych <= 'u') { gotoCase = 127; continue; }; if (yych <= 'v') { gotoCase = 125; continue; }; { gotoCase = 128; continue; }; } } } case 133: ++cursor; yych = this._charAt(cursor); { gotoCase = 123; continue; }; case this.case_NODIV: yych = this._charAt(cursor); if (yych <= '9') { if (yych <= '(') { if (yych <= '#') { if (yych <= ' ') { gotoCase = 136; continue; }; if (yych <= '!') { gotoCase = 138; continue; }; if (yych <= '"') { gotoCase = 140; continue; }; } else { if (yych <= '%') { if (yych <= '$') { gotoCase = 141; continue; }; { gotoCase = 143; continue; }; } else { if (yych <= '&') { gotoCase = 144; continue; }; if (yych <= '\'') { gotoCase = 145; continue; }; { gotoCase = 146; continue; }; } } } else { if (yych <= ',') { if (yych <= ')') { gotoCase = 147; continue; }; if (yych <= '*') { gotoCase = 149; continue; }; if (yych <= '+') { gotoCase = 150; continue; }; { gotoCase = 146; continue; }; } else { if (yych <= '.') { if (yych <= '-') { gotoCase = 151; continue; }; { gotoCase = 152; continue; }; } else { if (yych <= '/') { gotoCase = 153; continue; }; if (yych <= '0') { gotoCase = 154; continue; }; { gotoCase = 156; continue; }; } } } } else { if (yych <= '\\') { if (yych <= '>') { if (yych <= ';') { gotoCase = 146; continue; }; if (yych <= '<') { gotoCase = 157; continue; }; if (yych <= '=') { gotoCase = 158; continue; }; { gotoCase = 159; continue; }; } else { if (yych <= '@') { if (yych <= '?') { gotoCase = 146; continue; }; } else { if (yych <= 'Z') { gotoCase = 141; continue; }; if (yych <= '[') { gotoCase = 146; continue; }; { gotoCase = 160; continue; }; } } } else { if (yych <= 'z') { if (yych <= '^') { if (yych <= ']') { gotoCase = 146; continue; }; { gotoCase = 161; continue; }; } else { if (yych != '`') { gotoCase = 141; continue; }; } } else { if (yych <= '|') { if (yych <= '{') { gotoCase = 146; continue; }; { gotoCase = 162; continue; }; } else { if (yych <= '~') { gotoCase = 146; continue; }; if (yych >= 0x80) { gotoCase = 141; continue; }; } } } } case 136: ++cursor; case 137: { this.tokenType = null; return cursor; } case 138: ++cursor; if ((yych = this._charAt(cursor)) == '=') { gotoCase = 260; continue; }; case 139: { var token = this._line.charAt(cursorOnEnter); if (token === "{") this.tokenType = "block-start"; else if (token === "}") this.tokenType = "block-end"; else this.tokenType = null; return cursor; } case 140: yyaccept = 0; yych = this._charAt(YYMARKER = ++cursor); if (yych == '\n') { gotoCase = 137; continue; }; if (yych == '\r') { gotoCase = 137; continue; }; { gotoCase = 252; continue; }; case 141: yyaccept = 1; yych = this._charAt(YYMARKER = ++cursor); { gotoCase = 170; continue; }; case 142: this.setLexCondition(this._lexConditions.DIV); { var token = this._line.substring(cursorOnEnter, cursor); if (WebInspector.SourceJavaScriptTokenizer.Keywords[token] === true && token !== "__proto__") this.tokenType = "javascript-keyword"; else this.tokenType = "javascript-ident"; return cursor; } case 143: yych = this._charAt(++cursor); if (yych == '=') { gotoCase = 163; continue; }; { gotoCase = 139; continue; }; case 144: yych = this._charAt(++cursor); if (yych == '&') { gotoCase = 163; continue; }; if (yych == '=') { gotoCase = 163; continue; }; { gotoCase = 139; continue; }; case 145: yyaccept = 0; yych = this._charAt(YYMARKER = ++cursor); if (yych == '\n') { gotoCase = 137; continue; }; if (yych == '\r') { gotoCase = 137; continue; }; { gotoCase = 241; continue; }; case 146: yych = this._charAt(++cursor); { gotoCase = 139; continue; }; case 147: ++cursor; this.setLexCondition(this._lexConditions.DIV); { this.tokenType = null; return cursor; } case 149: yych = this._charAt(++cursor); if (yych == '=') { gotoCase = 163; continue; }; { gotoCase = 139; continue; }; case 150: yych = this._charAt(++cursor); if (yych == '+') { gotoCase = 163; continue; }; if (yych == '=') { gotoCase = 163; continue; }; { gotoCase = 139; continue; }; case 151: yych = this._charAt(++cursor); if (yych == '-') { gotoCase = 163; continue; }; if (yych == '=') { gotoCase = 163; continue; }; { gotoCase = 139; continue; }; case 152: yych = this._charAt(++cursor); if (yych <= '/') { gotoCase = 139; continue; }; if (yych <= '9') { gotoCase = 234; continue; }; { gotoCase = 139; continue; }; case 153: yyaccept = 0; yych = this._charAt(YYMARKER = ++cursor); if (yych <= '*') { if (yych <= '\f') { if (yych == '\n') { gotoCase = 137; continue; }; { gotoCase = 197; continue; }; } else { if (yych <= '\r') { gotoCase = 137; continue; }; if (yych <= ')') { gotoCase = 197; continue; }; { gotoCase = 202; continue; }; } } else { if (yych <= 'Z') { if (yych == '/') { gotoCase = 204; continue; }; { gotoCase = 197; continue; }; } else { if (yych <= '[') { gotoCase = 200; continue; }; if (yych <= '\\') { gotoCase = 199; continue; }; if (yych <= ']') { gotoCase = 137; continue; }; { gotoCase = 197; continue; }; } } case 154: yyaccept = 2; yych = this._charAt(YYMARKER = ++cursor); if (yych <= 'E') { if (yych <= '/') { if (yych == '.') { gotoCase = 183; continue; }; } else { if (yych <= '7') { gotoCase = 192; continue; }; if (yych >= 'E') { gotoCase = 182; continue; }; } } else { if (yych <= 'd') { if (yych == 'X') { gotoCase = 194; continue; }; } else { if (yych <= 'e') { gotoCase = 182; continue; }; if (yych == 'x') { gotoCase = 194; continue; }; } } case 155: this.setLexCondition(this._lexConditions.DIV); { this.tokenType = "javascript-number"; return cursor; } case 156: yyaccept = 2; yych = this._charAt(YYMARKER = ++cursor); if (yych <= '9') { if (yych == '.') { gotoCase = 183; continue; }; if (yych <= '/') { gotoCase = 155; continue; }; { gotoCase = 180; continue; }; } else { if (yych <= 'E') { if (yych <= 'D') { gotoCase = 155; continue; }; { gotoCase = 182; continue; }; } else { if (yych == 'e') { gotoCase = 182; continue; }; { gotoCase = 155; continue; }; } } case 157: yych = this._charAt(++cursor); if (yych <= ';') { gotoCase = 139; continue; }; if (yych <= '<') { gotoCase = 179; continue; }; if (yych <= '=') { gotoCase = 163; continue; }; { gotoCase = 139; continue; }; case 158: yych = this._charAt(++cursor); if (yych == '=') { gotoCase = 178; continue; }; { gotoCase = 139; continue; }; case 159: yych = this._charAt(++cursor); if (yych <= '<') { gotoCase = 139; continue; }; if (yych <= '=') { gotoCase = 163; continue; }; if (yych <= '>') { gotoCase = 176; continue; }; { gotoCase = 139; continue; }; case 160: yyaccept = 0; yych = this._charAt(YYMARKER = ++cursor); if (yych == 'u') { gotoCase = 164; continue; }; { gotoCase = 137; continue; }; case 161: yych = this._charAt(++cursor); if (yych == '=') { gotoCase = 163; continue; }; { gotoCase = 139; continue; }; case 162: yych = this._charAt(++cursor); if (yych == '=') { gotoCase = 163; continue; }; if (yych != '|') { gotoCase = 139; continue; }; case 163: yych = this._charAt(++cursor); { gotoCase = 139; continue; }; case 164: yych = this._charAt(++cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 165; continue; }; if (yych <= '9') { gotoCase = 166; continue; }; } else { if (yych <= 'F') { gotoCase = 166; continue; }; if (yych <= '`') { gotoCase = 165; continue; }; if (yych <= 'f') { gotoCase = 166; continue; }; } case 165: cursor = YYMARKER; if (yyaccept <= 1) { if (yyaccept <= 0) { { gotoCase = 137; continue; }; } else { { gotoCase = 142; continue; }; } } else { if (yyaccept <= 2) { { gotoCase = 155; continue; }; } else { { gotoCase = 217; continue; }; } } case 166: yych = this._charAt(++cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 165; continue; }; if (yych >= ':') { gotoCase = 165; continue; }; } else { if (yych <= 'F') { gotoCase = 167; continue; }; if (yych <= '`') { gotoCase = 165; continue; }; if (yych >= 'g') { gotoCase = 165; continue; }; } case 167: yych = this._charAt(++cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 165; continue; }; if (yych >= ':') { gotoCase = 165; continue; }; } else { if (yych <= 'F') { gotoCase = 168; continue; }; if (yych <= '`') { gotoCase = 165; continue; }; if (yych >= 'g') { gotoCase = 165; continue; }; } case 168: yych = this._charAt(++cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 165; continue; }; if (yych >= ':') { gotoCase = 165; continue; }; } else { if (yych <= 'F') { gotoCase = 169; continue; }; if (yych <= '`') { gotoCase = 165; continue; }; if (yych >= 'g') { gotoCase = 165; continue; }; } case 169: yyaccept = 1; YYMARKER = ++cursor; yych = this._charAt(cursor); case 170: if (yych <= '[') { if (yych <= '/') { if (yych == '$') { gotoCase = 169; continue; }; { gotoCase = 142; continue; }; } else { if (yych <= '9') { gotoCase = 169; continue; }; if (yych <= '@') { gotoCase = 142; continue; }; if (yych <= 'Z') { gotoCase = 169; continue; }; { gotoCase = 142; continue; }; } } else { if (yych <= '_') { if (yych <= '\\') { gotoCase = 171; continue; }; if (yych <= '^') { gotoCase = 142; continue; }; { gotoCase = 169; continue; }; } else { if (yych <= '`') { gotoCase = 142; continue; }; if (yych <= 'z') { gotoCase = 169; continue; }; if (yych <= String.fromCharCode(0x7F)) { gotoCase = 142; continue; }; { gotoCase = 169; continue; }; } } case 171: ++cursor; yych = this._charAt(cursor); if (yych != 'u') { gotoCase = 165; continue; }; ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 165; continue; }; if (yych >= ':') { gotoCase = 165; continue; }; } else { if (yych <= 'F') { gotoCase = 173; continue; }; if (yych <= '`') { gotoCase = 165; continue; }; if (yych >= 'g') { gotoCase = 165; continue; }; } case 173: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 165; continue; }; if (yych >= ':') { gotoCase = 165; continue; }; } else { if (yych <= 'F') { gotoCase = 174; continue; }; if (yych <= '`') { gotoCase = 165; continue; }; if (yych >= 'g') { gotoCase = 165; continue; }; } case 174: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 165; continue; }; if (yych >= ':') { gotoCase = 165; continue; }; } else { if (yych <= 'F') { gotoCase = 175; continue; }; if (yych <= '`') { gotoCase = 165; continue; }; if (yych >= 'g') { gotoCase = 165; continue; }; } case 175: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 165; continue; }; if (yych <= '9') { gotoCase = 169; continue; }; { gotoCase = 165; continue; }; } else { if (yych <= 'F') { gotoCase = 169; continue; }; if (yych <= '`') { gotoCase = 165; continue; }; if (yych <= 'f') { gotoCase = 169; continue; }; { gotoCase = 165; continue; }; } case 176: yych = this._charAt(++cursor); if (yych <= '<') { gotoCase = 139; continue; }; if (yych <= '=') { gotoCase = 163; continue; }; if (yych >= '?') { gotoCase = 139; continue; }; yych = this._charAt(++cursor); if (yych == '=') { gotoCase = 163; continue; }; { gotoCase = 139; continue; }; case 178: yych = this._charAt(++cursor); if (yych == '=') { gotoCase = 163; continue; }; { gotoCase = 139; continue; }; case 179: yych = this._charAt(++cursor); if (yych == '=') { gotoCase = 163; continue; }; { gotoCase = 139; continue; }; case 180: yyaccept = 2; YYMARKER = ++cursor; yych = this._charAt(cursor); if (yych <= '9') { if (yych == '.') { gotoCase = 183; continue; }; if (yych <= '/') { gotoCase = 155; continue; }; { gotoCase = 180; continue; }; } else { if (yych <= 'E') { if (yych <= 'D') { gotoCase = 155; continue; }; } else { if (yych != 'e') { gotoCase = 155; continue; }; } } case 182: yych = this._charAt(++cursor); if (yych <= ',') { if (yych == '+') { gotoCase = 189; continue; }; { gotoCase = 165; continue; }; } else { if (yych <= '-') { gotoCase = 189; continue; }; if (yych <= '/') { gotoCase = 165; continue; }; if (yych <= '9') { gotoCase = 190; continue; }; { gotoCase = 165; continue; }; } case 183: yyaccept = 2; YYMARKER = ++cursor; yych = this._charAt(cursor); if (yych <= 'D') { if (yych <= '/') { gotoCase = 155; continue; }; if (yych <= '9') { gotoCase = 183; continue; }; { gotoCase = 155; continue; }; } else { if (yych <= 'E') { gotoCase = 185; continue; }; if (yych != 'e') { gotoCase = 155; continue; }; } case 185: yych = this._charAt(++cursor); if (yych <= ',') { if (yych != '+') { gotoCase = 165; continue; }; } else { if (yych <= '-') { gotoCase = 186; continue; }; if (yych <= '/') { gotoCase = 165; continue; }; if (yych <= '9') { gotoCase = 187; continue; }; { gotoCase = 165; continue; }; } case 186: yych = this._charAt(++cursor); if (yych <= '/') { gotoCase = 165; continue; }; if (yych >= ':') { gotoCase = 165; continue; }; case 187: ++cursor; yych = this._charAt(cursor); if (yych <= '/') { gotoCase = 155; continue; }; if (yych <= '9') { gotoCase = 187; continue; }; { gotoCase = 155; continue; }; case 189: yych = this._charAt(++cursor); if (yych <= '/') { gotoCase = 165; continue; }; if (yych >= ':') { gotoCase = 165; continue; }; case 190: ++cursor; yych = this._charAt(cursor); if (yych <= '/') { gotoCase = 155; continue; }; if (yych <= '9') { gotoCase = 190; continue; }; { gotoCase = 155; continue; }; case 192: ++cursor; yych = this._charAt(cursor); if (yych <= '/') { gotoCase = 155; continue; }; if (yych <= '7') { gotoCase = 192; continue; }; { gotoCase = 155; continue; }; case 194: yych = this._charAt(++cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 165; continue; }; if (yych >= ':') { gotoCase = 165; continue; }; } else { if (yych <= 'F') { gotoCase = 195; continue; }; if (yych <= '`') { gotoCase = 165; continue; }; if (yych >= 'g') { gotoCase = 165; continue; }; } case 195: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 155; continue; }; if (yych <= '9') { gotoCase = 195; continue; }; { gotoCase = 155; continue; }; } else { if (yych <= 'F') { gotoCase = 195; continue; }; if (yych <= '`') { gotoCase = 155; continue; }; if (yych <= 'f') { gotoCase = 195; continue; }; { gotoCase = 155; continue; }; } case 197: ++cursor; yych = this._charAt(cursor); if (yych <= '.') { if (yych <= '\n') { if (yych <= '\t') { gotoCase = 197; continue; }; { gotoCase = 165; continue; }; } else { if (yych == '\r') { gotoCase = 165; continue; }; { gotoCase = 197; continue; }; } } else { if (yych <= '[') { if (yych <= '/') { gotoCase = 220; continue; }; if (yych <= 'Z') { gotoCase = 197; continue; }; { gotoCase = 228; continue; }; } else { if (yych <= '\\') { gotoCase = 227; continue; }; if (yych <= ']') { gotoCase = 165; continue; }; { gotoCase = 197; continue; }; } } case 199: yych = this._charAt(++cursor); if (yych == '\n') { gotoCase = 165; continue; }; if (yych == '\r') { gotoCase = 165; continue; }; { gotoCase = 197; continue; }; case 200: ++cursor; yych = this._charAt(cursor); if (yych <= '*') { if (yych <= '\f') { if (yych == '\n') { gotoCase = 165; continue; }; { gotoCase = 200; continue; }; } else { if (yych <= '\r') { gotoCase = 165; continue; }; if (yych <= ')') { gotoCase = 200; continue; }; { gotoCase = 165; continue; }; } } else { if (yych <= '[') { if (yych == '/') { gotoCase = 165; continue; }; { gotoCase = 200; continue; }; } else { if (yych <= '\\') { gotoCase = 215; continue; }; if (yych <= ']') { gotoCase = 213; continue; }; { gotoCase = 200; continue; }; } } case 202: ++cursor; yych = this._charAt(cursor); if (yych <= '\f') { if (yych == '\n') { gotoCase = 209; continue; }; { gotoCase = 202; continue; }; } else { if (yych <= '\r') { gotoCase = 209; continue; }; if (yych == '*') { gotoCase = 207; continue; }; { gotoCase = 202; continue; }; } case 204: ++cursor; yych = this._charAt(cursor); if (yych == '\n') { gotoCase = 206; continue; }; if (yych != '\r') { gotoCase = 204; continue; }; case 206: { this.tokenType = "javascript-comment"; return cursor; } case 207: ++cursor; yych = this._charAt(cursor); if (yych == '*') { gotoCase = 207; continue; }; if (yych == '/') { gotoCase = 211; continue; }; { gotoCase = 202; continue; }; case 209: ++cursor; this.setLexCondition(this._lexConditions.COMMENT); { this.tokenType = "javascript-comment"; return cursor; } case 211: ++cursor; { this.tokenType = "javascript-comment"; return cursor; } case 213: ++cursor; yych = this._charAt(cursor); if (yych <= '*') { if (yych <= '\f') { if (yych == '\n') { gotoCase = 165; continue; }; { gotoCase = 213; continue; }; } else { if (yych <= '\r') { gotoCase = 165; continue; }; if (yych <= ')') { gotoCase = 213; continue; }; { gotoCase = 197; continue; }; } } else { if (yych <= 'Z') { if (yych == '/') { gotoCase = 220; continue; }; { gotoCase = 213; continue; }; } else { if (yych <= '[') { gotoCase = 218; continue; }; if (yych <= '\\') { gotoCase = 216; continue; }; { gotoCase = 213; continue; }; } } case 215: ++cursor; yych = this._charAt(cursor); if (yych == '\n') { gotoCase = 165; continue; }; if (yych == '\r') { gotoCase = 165; continue; }; { gotoCase = 200; continue; }; case 216: yyaccept = 3; YYMARKER = ++cursor; yych = this._charAt(cursor); if (yych == '\n') { gotoCase = 217; continue; }; if (yych != '\r') { gotoCase = 213; continue; }; case 217: this.setLexCondition(this._lexConditions.REGEX); { this.tokenType = "javascript-regexp"; return cursor; } case 218: ++cursor; yych = this._charAt(cursor); if (yych <= '*') { if (yych <= '\f') { if (yych == '\n') { gotoCase = 165; continue; }; { gotoCase = 218; continue; }; } else { if (yych <= '\r') { gotoCase = 165; continue; }; if (yych <= ')') { gotoCase = 218; continue; }; { gotoCase = 165; continue; }; } } else { if (yych <= '[') { if (yych == '/') { gotoCase = 165; continue; }; { gotoCase = 218; continue; }; } else { if (yych <= '\\') { gotoCase = 225; continue; }; if (yych <= ']') { gotoCase = 223; continue; }; { gotoCase = 218; continue; }; } } case 220: ++cursor; yych = this._charAt(cursor); if (yych <= 'h') { if (yych == 'g') { gotoCase = 220; continue; }; } else { if (yych <= 'i') { gotoCase = 220; continue; }; if (yych == 'm') { gotoCase = 220; continue; }; } { this.tokenType = "javascript-regexp"; return cursor; } case 223: ++cursor; yych = this._charAt(cursor); if (yych <= '*') { if (yych <= '\f') { if (yych == '\n') { gotoCase = 165; continue; }; { gotoCase = 223; continue; }; } else { if (yych <= '\r') { gotoCase = 165; continue; }; if (yych <= ')') { gotoCase = 223; continue; }; { gotoCase = 197; continue; }; } } else { if (yych <= 'Z') { if (yych == '/') { gotoCase = 220; continue; }; { gotoCase = 223; continue; }; } else { if (yych <= '[') { gotoCase = 218; continue; }; if (yych <= '\\') { gotoCase = 226; continue; }; { gotoCase = 223; continue; }; } } case 225: ++cursor; yych = this._charAt(cursor); if (yych == '\n') { gotoCase = 165; continue; }; if (yych == '\r') { gotoCase = 165; continue; }; { gotoCase = 218; continue; }; case 226: yyaccept = 3; YYMARKER = ++cursor; yych = this._charAt(cursor); if (yych == '\n') { gotoCase = 217; continue; }; if (yych == '\r') { gotoCase = 217; continue; }; { gotoCase = 223; continue; }; case 227: yyaccept = 3; YYMARKER = ++cursor; yych = this._charAt(cursor); if (yych == '\n') { gotoCase = 217; continue; }; if (yych == '\r') { gotoCase = 217; continue; }; { gotoCase = 197; continue; }; case 228: ++cursor; yych = this._charAt(cursor); if (yych <= '*') { if (yych <= '\f') { if (yych == '\n') { gotoCase = 165; continue; }; { gotoCase = 228; continue; }; } else { if (yych <= '\r') { gotoCase = 165; continue; }; if (yych <= ')') { gotoCase = 228; continue; }; { gotoCase = 165; continue; }; } } else { if (yych <= '[') { if (yych == '/') { gotoCase = 165; continue; }; { gotoCase = 228; continue; }; } else { if (yych <= '\\') { gotoCase = 232; continue; }; if (yych >= '^') { gotoCase = 228; continue; }; } } case 230: ++cursor; yych = this._charAt(cursor); if (yych <= '*') { if (yych <= '\f') { if (yych == '\n') { gotoCase = 165; continue; }; { gotoCase = 230; continue; }; } else { if (yych <= '\r') { gotoCase = 165; continue; }; if (yych <= ')') { gotoCase = 230; continue; }; { gotoCase = 197; continue; }; } } else { if (yych <= 'Z') { if (yych == '/') { gotoCase = 220; continue; }; { gotoCase = 230; continue; }; } else { if (yych <= '[') { gotoCase = 228; continue; }; if (yych <= '\\') { gotoCase = 233; continue; }; { gotoCase = 230; continue; }; } } case 232: ++cursor; yych = this._charAt(cursor); if (yych == '\n') { gotoCase = 165; continue; }; if (yych == '\r') { gotoCase = 165; continue; }; { gotoCase = 228; continue; }; case 233: yyaccept = 3; YYMARKER = ++cursor; yych = this._charAt(cursor); if (yych == '\n') { gotoCase = 217; continue; }; if (yych == '\r') { gotoCase = 217; continue; }; { gotoCase = 230; continue; }; case 234: yyaccept = 2; YYMARKER = ++cursor; yych = this._charAt(cursor); if (yych <= 'D') { if (yych <= '/') { gotoCase = 155; continue; }; if (yych <= '9') { gotoCase = 234; continue; }; { gotoCase = 155; continue; }; } else { if (yych <= 'E') { gotoCase = 236; continue; }; if (yych != 'e') { gotoCase = 155; continue; }; } case 236: yych = this._charAt(++cursor); if (yych <= ',') { if (yych != '+') { gotoCase = 165; continue; }; } else { if (yych <= '-') { gotoCase = 237; continue; }; if (yych <= '/') { gotoCase = 165; continue; }; if (yych <= '9') { gotoCase = 238; continue; }; { gotoCase = 165; continue; }; } case 237: yych = this._charAt(++cursor); if (yych <= '/') { gotoCase = 165; continue; }; if (yych >= ':') { gotoCase = 165; continue; }; case 238: ++cursor; yych = this._charAt(cursor); if (yych <= '/') { gotoCase = 155; continue; }; if (yych <= '9') { gotoCase = 238; continue; }; { gotoCase = 155; continue; }; case 240: ++cursor; yych = this._charAt(cursor); case 241: if (yych <= '\r') { if (yych == '\n') { gotoCase = 165; continue; }; if (yych <= '\f') { gotoCase = 240; continue; }; { gotoCase = 165; continue; }; } else { if (yych <= '\'') { if (yych <= '&') { gotoCase = 240; continue; }; { gotoCase = 243; continue; }; } else { if (yych != '\\') { gotoCase = 240; continue; }; } } ++cursor; yych = this._charAt(cursor); if (yych <= 'a') { if (yych <= '!') { if (yych <= '\n') { if (yych <= '\t') { gotoCase = 165; continue; }; { gotoCase = 246; continue; }; } else { if (yych == '\r') { gotoCase = 246; continue; }; { gotoCase = 165; continue; }; } } else { if (yych <= '\'') { if (yych <= '"') { gotoCase = 240; continue; }; if (yych <= '&') { gotoCase = 165; continue; }; { gotoCase = 240; continue; }; } else { if (yych == '\\') { gotoCase = 240; continue; }; { gotoCase = 165; continue; }; } } } else { if (yych <= 'q') { if (yych <= 'f') { if (yych <= 'b') { gotoCase = 240; continue; }; if (yych <= 'e') { gotoCase = 165; continue; }; { gotoCase = 240; continue; }; } else { if (yych == 'n') { gotoCase = 240; continue; }; { gotoCase = 165; continue; }; } } else { if (yych <= 't') { if (yych == 's') { gotoCase = 165; continue; }; { gotoCase = 240; continue; }; } else { if (yych <= 'u') { gotoCase = 245; continue; }; if (yych <= 'v') { gotoCase = 240; continue; }; { gotoCase = 165; continue; }; } } } case 243: ++cursor; { this.tokenType = "javascript-string"; return cursor; } case 245: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 165; continue; }; if (yych <= '9') { gotoCase = 248; continue; }; { gotoCase = 165; continue; }; } else { if (yych <= 'F') { gotoCase = 248; continue; }; if (yych <= '`') { gotoCase = 165; continue; }; if (yych <= 'f') { gotoCase = 248; continue; }; { gotoCase = 165; continue; }; } case 246: ++cursor; this.setLexCondition(this._lexConditions.SSTRING); { this.tokenType = "javascript-string"; return cursor; } case 248: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 165; continue; }; if (yych >= ':') { gotoCase = 165; continue; }; } else { if (yych <= 'F') { gotoCase = 249; continue; }; if (yych <= '`') { gotoCase = 165; continue; }; if (yych >= 'g') { gotoCase = 165; continue; }; } case 249: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 165; continue; }; if (yych >= ':') { gotoCase = 165; continue; }; } else { if (yych <= 'F') { gotoCase = 250; continue; }; if (yych <= '`') { gotoCase = 165; continue; }; if (yych >= 'g') { gotoCase = 165; continue; }; } case 250: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 165; continue; }; if (yych <= '9') { gotoCase = 240; continue; }; { gotoCase = 165; continue; }; } else { if (yych <= 'F') { gotoCase = 240; continue; }; if (yych <= '`') { gotoCase = 165; continue; }; if (yych <= 'f') { gotoCase = 240; continue; }; { gotoCase = 165; continue; }; } case 251: ++cursor; yych = this._charAt(cursor); case 252: if (yych <= '\r') { if (yych == '\n') { gotoCase = 165; continue; }; if (yych <= '\f') { gotoCase = 251; continue; }; { gotoCase = 165; continue; }; } else { if (yych <= '"') { if (yych <= '!') { gotoCase = 251; continue; }; { gotoCase = 243; continue; }; } else { if (yych != '\\') { gotoCase = 251; continue; }; } } ++cursor; yych = this._charAt(cursor); if (yych <= 'a') { if (yych <= '!') { if (yych <= '\n') { if (yych <= '\t') { gotoCase = 165; continue; }; { gotoCase = 255; continue; }; } else { if (yych == '\r') { gotoCase = 255; continue; }; { gotoCase = 165; continue; }; } } else { if (yych <= '\'') { if (yych <= '"') { gotoCase = 251; continue; }; if (yych <= '&') { gotoCase = 165; continue; }; { gotoCase = 251; continue; }; } else { if (yych == '\\') { gotoCase = 251; continue; }; { gotoCase = 165; continue; }; } } } else { if (yych <= 'q') { if (yych <= 'f') { if (yych <= 'b') { gotoCase = 251; continue; }; if (yych <= 'e') { gotoCase = 165; continue; }; { gotoCase = 251; continue; }; } else { if (yych == 'n') { gotoCase = 251; continue; }; { gotoCase = 165; continue; }; } } else { if (yych <= 't') { if (yych == 's') { gotoCase = 165; continue; }; { gotoCase = 251; continue; }; } else { if (yych <= 'u') { gotoCase = 254; continue; }; if (yych <= 'v') { gotoCase = 251; continue; }; { gotoCase = 165; continue; }; } } } case 254: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 165; continue; }; if (yych <= '9') { gotoCase = 257; continue; }; { gotoCase = 165; continue; }; } else { if (yych <= 'F') { gotoCase = 257; continue; }; if (yych <= '`') { gotoCase = 165; continue; }; if (yych <= 'f') { gotoCase = 257; continue; }; { gotoCase = 165; continue; }; } case 255: ++cursor; this.setLexCondition(this._lexConditions.DSTRING); { this.tokenType = "javascript-string"; return cursor; } case 257: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 165; continue; }; if (yych >= ':') { gotoCase = 165; continue; }; } else { if (yych <= 'F') { gotoCase = 258; continue; }; if (yych <= '`') { gotoCase = 165; continue; }; if (yych >= 'g') { gotoCase = 165; continue; }; } case 258: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 165; continue; }; if (yych >= ':') { gotoCase = 165; continue; }; } else { if (yych <= 'F') { gotoCase = 259; continue; }; if (yych <= '`') { gotoCase = 165; continue; }; if (yych >= 'g') { gotoCase = 165; continue; }; } case 259: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 165; continue; }; if (yych <= '9') { gotoCase = 251; continue; }; { gotoCase = 165; continue; }; } else { if (yych <= 'F') { gotoCase = 251; continue; }; if (yych <= '`') { gotoCase = 165; continue; }; if (yych <= 'f') { gotoCase = 251; continue; }; { gotoCase = 165; continue; }; } case 260: ++cursor; if ((yych = this._charAt(cursor)) == '=') { gotoCase = 163; continue; }; { gotoCase = 139; continue; }; case this.case_REGEX: yych = this._charAt(cursor); if (yych <= '.') { if (yych <= '\n') { if (yych <= '\t') { gotoCase = 264; continue; }; { gotoCase = 265; continue; }; } else { if (yych == '\r') { gotoCase = 265; continue; }; { gotoCase = 264; continue; }; } } else { if (yych <= '[') { if (yych <= '/') { gotoCase = 267; continue; }; if (yych <= 'Z') { gotoCase = 264; continue; }; { gotoCase = 269; continue; }; } else { if (yych <= '\\') { gotoCase = 270; continue; }; if (yych <= ']') { gotoCase = 265; continue; }; { gotoCase = 264; continue; }; } } case 263: { this.tokenType = "javascript-regexp"; return cursor; } case 264: yyaccept = 0; yych = this._charAt(YYMARKER = ++cursor); { gotoCase = 272; continue; }; case 265: ++cursor; case 266: { this.tokenType = null; return cursor; } case 267: ++cursor; yych = this._charAt(cursor); { gotoCase = 278; continue; }; case 268: this.setLexCondition(this._lexConditions.NODIV); { this.tokenType = "javascript-regexp"; return cursor; } case 269: yyaccept = 1; yych = this._charAt(YYMARKER = ++cursor); if (yych <= '\r') { if (yych == '\n') { gotoCase = 266; continue; }; if (yych <= '\f') { gotoCase = 276; continue; }; { gotoCase = 266; continue; }; } else { if (yych <= '*') { if (yych <= ')') { gotoCase = 276; continue; }; { gotoCase = 266; continue; }; } else { if (yych == '/') { gotoCase = 266; continue; }; { gotoCase = 276; continue; }; } } case 270: yych = this._charAt(++cursor); if (yych == '\n') { gotoCase = 266; continue; }; if (yych == '\r') { gotoCase = 266; continue; }; case 271: yyaccept = 0; YYMARKER = ++cursor; yych = this._charAt(cursor); case 272: if (yych <= '.') { if (yych <= '\n') { if (yych <= '\t') { gotoCase = 271; continue; }; { gotoCase = 263; continue; }; } else { if (yych == '\r') { gotoCase = 263; continue; }; { gotoCase = 271; continue; }; } } else { if (yych <= '[') { if (yych <= '/') { gotoCase = 277; continue; }; if (yych <= 'Z') { gotoCase = 271; continue; }; { gotoCase = 275; continue; }; } else { if (yych <= '\\') { gotoCase = 273; continue; }; if (yych <= ']') { gotoCase = 263; continue; }; { gotoCase = 271; continue; }; } } case 273: ++cursor; yych = this._charAt(cursor); if (yych == '\n') { gotoCase = 274; continue; }; if (yych != '\r') { gotoCase = 271; continue; }; case 274: cursor = YYMARKER; if (yyaccept <= 0) { { gotoCase = 263; continue; }; } else { { gotoCase = 266; continue; }; } case 275: ++cursor; yych = this._charAt(cursor); case 276: if (yych <= '*') { if (yych <= '\f') { if (yych == '\n') { gotoCase = 274; continue; }; { gotoCase = 275; continue; }; } else { if (yych <= '\r') { gotoCase = 274; continue; }; if (yych <= ')') { gotoCase = 275; continue; }; { gotoCase = 274; continue; }; } } else { if (yych <= '[') { if (yych == '/') { gotoCase = 274; continue; }; { gotoCase = 275; continue; }; } else { if (yych <= '\\') { gotoCase = 281; continue; }; if (yych <= ']') { gotoCase = 279; continue; }; { gotoCase = 275; continue; }; } } case 277: ++cursor; yych = this._charAt(cursor); case 278: if (yych <= 'h') { if (yych == 'g') { gotoCase = 277; continue; }; { gotoCase = 268; continue; }; } else { if (yych <= 'i') { gotoCase = 277; continue; }; if (yych == 'm') { gotoCase = 277; continue; }; { gotoCase = 268; continue; }; } case 279: yyaccept = 0; YYMARKER = ++cursor; yych = this._charAt(cursor); if (yych <= '*') { if (yych <= '\f') { if (yych == '\n') { gotoCase = 263; continue; }; { gotoCase = 279; continue; }; } else { if (yych <= '\r') { gotoCase = 263; continue; }; if (yych <= ')') { gotoCase = 279; continue; }; { gotoCase = 271; continue; }; } } else { if (yych <= 'Z') { if (yych == '/') { gotoCase = 277; continue; }; { gotoCase = 279; continue; }; } else { if (yych <= '[') { gotoCase = 275; continue; }; if (yych <= '\\') { gotoCase = 282; continue; }; { gotoCase = 279; continue; }; } } case 281: ++cursor; yych = this._charAt(cursor); if (yych == '\n') { gotoCase = 274; continue; }; if (yych == '\r') { gotoCase = 274; continue; }; { gotoCase = 275; continue; }; case 282: ++cursor; yych = this._charAt(cursor); if (yych == '\n') { gotoCase = 274; continue; }; if (yych == '\r') { gotoCase = 274; continue; }; { gotoCase = 279; continue; }; case this.case_SSTRING: yych = this._charAt(cursor); if (yych <= '\r') { if (yych == '\n') { gotoCase = 287; continue; }; if (yych <= '\f') { gotoCase = 286; continue; }; { gotoCase = 287; continue; }; } else { if (yych <= '\'') { if (yych <= '&') { gotoCase = 286; continue; }; { gotoCase = 289; continue; }; } else { if (yych == '\\') { gotoCase = 291; continue; }; { gotoCase = 286; continue; }; } } case 285: { this.tokenType = "javascript-string"; return cursor; } case 286: yyaccept = 0; yych = this._charAt(YYMARKER = ++cursor); { gotoCase = 293; continue; }; case 287: ++cursor; case 288: { this.tokenType = null; return cursor; } case 289: ++cursor; case 290: this.setLexCondition(this._lexConditions.NODIV); { this.tokenType = "javascript-string"; return cursor; } case 291: yyaccept = 1; yych = this._charAt(YYMARKER = ++cursor); if (yych <= 'e') { if (yych <= '\'') { if (yych == '"') { gotoCase = 292; continue; }; if (yych <= '&') { gotoCase = 288; continue; }; } else { if (yych <= '\\') { if (yych <= '[') { gotoCase = 288; continue; }; } else { if (yych != 'b') { gotoCase = 288; continue; }; } } } else { if (yych <= 'r') { if (yych <= 'm') { if (yych >= 'g') { gotoCase = 288; continue; }; } else { if (yych <= 'n') { gotoCase = 292; continue; }; if (yych <= 'q') { gotoCase = 288; continue; }; } } else { if (yych <= 't') { if (yych <= 's') { gotoCase = 288; continue; }; } else { if (yych <= 'u') { gotoCase = 294; continue; }; if (yych >= 'w') { gotoCase = 288; continue; }; } } } case 292: yyaccept = 0; YYMARKER = ++cursor; yych = this._charAt(cursor); case 293: if (yych <= '\r') { if (yych == '\n') { gotoCase = 285; continue; }; if (yych <= '\f') { gotoCase = 292; continue; }; { gotoCase = 285; continue; }; } else { if (yych <= '\'') { if (yych <= '&') { gotoCase = 292; continue; }; { gotoCase = 300; continue; }; } else { if (yych == '\\') { gotoCase = 299; continue; }; { gotoCase = 292; continue; }; } } case 294: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 295; continue; }; if (yych <= '9') { gotoCase = 296; continue; }; } else { if (yych <= 'F') { gotoCase = 296; continue; }; if (yych <= '`') { gotoCase = 295; continue; }; if (yych <= 'f') { gotoCase = 296; continue; }; } case 295: cursor = YYMARKER; if (yyaccept <= 0) { { gotoCase = 285; continue; }; } else { { gotoCase = 288; continue; }; } case 296: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 295; continue; }; if (yych >= ':') { gotoCase = 295; continue; }; } else { if (yych <= 'F') { gotoCase = 297; continue; }; if (yych <= '`') { gotoCase = 295; continue; }; if (yych >= 'g') { gotoCase = 295; continue; }; } case 297: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 295; continue; }; if (yych >= ':') { gotoCase = 295; continue; }; } else { if (yych <= 'F') { gotoCase = 298; continue; }; if (yych <= '`') { gotoCase = 295; continue; }; if (yych >= 'g') { gotoCase = 295; continue; }; } case 298: ++cursor; yych = this._charAt(cursor); if (yych <= '@') { if (yych <= '/') { gotoCase = 295; continue; }; if (yych <= '9') { gotoCase = 292; continue; }; { gotoCase = 295; continue; }; } else { if (yych <= 'F') { gotoCase = 292; continue; }; if (yych <= '`') { gotoCase = 295; continue; }; if (yych <= 'f') { gotoCase = 292; continue; }; { gotoCase = 295; continue; }; } case 299: ++cursor; yych = this._charAt(cursor); if (yych <= 'e') { if (yych <= '\'') { if (yych == '"') { gotoCase = 292; continue; }; if (yych <= '&') { gotoCase = 295; continue; }; { gotoCase = 292; continue; }; } else { if (yych <= '\\') { if (yych <= '[') { gotoCase = 295; continue; }; { gotoCase = 292; continue; }; } else { if (yych == 'b') { gotoCase = 292; continue; }